
Imports System.IO
Imports ICombatEngine
Imports System.Drawing
Imports System.Windows.Forms
Imports System.ComponentModel
Imports System.Drawing.Drawing2D
Imports System.Runtime.Serialization
Imports System.Runtime.Serialization.Formatters.Binary

' Added Elements to Chits.
' Added Options to Element entry for future enhancement. An option could be... meltagun... etc.
' Added Moderator options: "Allow players to manage chits", "Use element pointvalue for chit pointvalue"

#Region "Enums"

Public Enum CampaignerItem_cgd
    Battlegroup = 1
    Unit = 2
    ElementGroup = 3
    Element = 4
    Installation = 5
    Token = 6

    waypoint = 21
    Faction = 22

    Advantage = 31
    Indicator = 32

    Rule = 64
    Resource = 65

End Enum

Public Enum VictoryConditionClass_cgd
    AreaObjective = 1
    AttritionObjective = 2
    ChitDestruction = 3
    Resource = 4
    Final = 99
End Enum

Public Enum MovementOrder_cgd
    Blitz = 1
    Advance = 2
    Combat = 3
    Slow = 4
    Hide = 5
    Digin = 6
End Enum

Public Enum ROE_cgd
    Halt = 1
    Retreat = 2
    Engage = 3
End Enum

<Serializable()> Public Enum OrderOfBattleUse_cgd
    UseOnlyOOB = 1
    AllowCreateUnit = 2 ' may use OOB units or create their own
    NoOOB = 3     ' only create units
End Enum

<Serializable()> Public Enum CoreRules_cgd
    None = 0
    Bridging            ' units can move as though through OPEN terrain within range of this rule
    Engineering       ' can build installations??
    [Protected]        ' disallows units to be deployed within it's range
    AirDrop              ' allows a unit to be 'redeployed', but must have airtransportable rule
    FieldCraft           ' allows a unit to move quickly through rough terrain, it is only affected 1/2 by movement penalties
    SpecialOps          ' reduces the effective ZOC of enemy units
    Scout                ' source terrain is not counted when determining LOS detection
    Deployment       ' within range of this rule is considered a deployment zone
    AirTransportable    ' allows a target unit to be 'redeployed'
End Enum

<Serializable()> Public Enum TurnLength_cgd
    FiveMinute = 0
    FifteenMinute = 1
    HalfHour = 2
    Hour = 3
    HalfDay = 4
    FullDay = 5
    Week = 6
    Month = 7
End Enum

<Serializable()> Public Enum IconImageIndex_cgd
    Owner = 0
    Enemy = 1
    SameFaction = 2
    Allied = 3
    Neutral = 4
End Enum

<Serializable()> Public Enum RuleApplies_cgd
    Constant = 0  ' always in effect, these rules should have NO max number of uses
    Combat = 1   ' only during combat can this rule be used. If it has 0 max uses, then it is a 'constant' in any combat
    NonCombat = 2 ' may only be used during the planning phase
End Enum

<Serializable()> Public Enum CaptureEvent_cgd
    ChangeOwnership = 0
    Hold = 1
    Destroyed = 2
End Enum

<Serializable()> Public Enum BattleResult_cgd
    NotFinished = 0
    AttackerVictory = 1
    DefenderVictory = 2
    AttackerMarginalVictory = 3
    DefenderMarginalVictory = 4
    Draw = 5
End Enum

<Serializable()> Public Enum UnitBattleResult_cgd
    NoBattle = 0
    Draw = 1
    MarginalVictory = 2
    Victory = 3
    MarginalDefeat = 4
    Defeat = 5
End Enum

<Serializable()> Public Enum BattlePosture_cgd
    NoBattle = 0
    Attacking = 1
    Defending = 2
    AttackingReserve = 3
    DefendingReserve = 4
    AttackingSupport = 5
    DefendingSupport = 6
    AttackingIndirectSupport = 7
    DefendingIndirectSupport = 8
End Enum

<Serializable()> Public Enum DiplomaticStanding_cgd
    SameFaction = 0
    Allied = 1
    Neutral = 2
    Enemy = 3
End Enum

<Serializable()> Public Enum GroundUnitStatus_cgd
    OK = 0
    Engaged = 1
    Moving = 2
    Assembling = 3
    Reinforcing = 4
    Regrouping = 5      '// one lightning bolt.
    Regrouped = 6
    Dead = 10
    Not_Deployed = 11
    'InTransport = 12    ' riding baby. Riding.

    Disarrayed = 24 '// a unit goes from disarrayed to regrouping to ok, two lightning bolts. Ouch.
    Scattered = 25   '// a unit goes from scattered to disarrayed if its not within an enemy ZOC. and there are three stinking 'bolts on this one.

    Out_Of_Command = 32
    Out_Of_Resource = 33  '// this happens when a unit has a constant rule that can't be "fed"

    Disbanded = 254 '// This is the HIGHEST number we can use due to historical data being saved as byte

End Enum

<Serializable()> Public Enum GroundChitClass_cgd
    Objective = 0
    Unit = 1
    Token = 2
    Battlegroup = 3
End Enum

Public Enum PlayerPOV_cgd
    Attacking = 1
    Defending = 2
End Enum

<Serializable()> Public Enum EventAuthorityLevel
    PublicEvent = 0  ' always shows up
    FriendlyEvent = 1   ' shows up on friendly factions
    OwningEvent = 2   ' only owning player shows up
    ModeratorEvent = 3  ' only shows for moderator
End Enum

<Serializable()> Public Enum CampaignerObjectType_cot
    objective = 0
    unit = 1
    token = 2
    battlegroup = 3
    rule = 4
    resource = 5
    order = 6
    player = 7
    faction = 8
    indicator = 9
    advantage = 10

    noItem = 254

End Enum

<Serializable()> Public Enum ChitDetectionLevel_cdl
    '// change this to extend the values, detected 1, detected 2, etc
    Undetected = 0
    Detected = 1
    Detected_high = 36
    Spotted = 37
    Spotted_high = 72
    Sighted = 90
    Sighted_high = 126
    Known = 127
    Known_high = 234
    Dead = 254 '// this is the highest value that can be used since it's saved as a byte
End Enum

#End Region

<Serializable()> Public Class CampaignerGameData

    Public Enum ModeratorFlag
        SealedGame = 0
        ModeratorReady = 1       '// does not HAVE to use a moderator for this campaign
        ModeratorRequired = 2
    End Enum

    Public Enum ChitDetectionLevel
        UnaccountedDL = 0
        UndetectedDL = 1
        DetectedDL = 2
        SightedDL = 4
        IdentifiedDL = 8
        KnownDL = 12
    End Enum

    Const C_Version As Single = 1.1
    ' this class is the base for a game, its properties and collections define all elements in the campaign
    Private mvarDemo As Boolean = False

    Private mvarGameName As String
    Private mvarVersion As String
    Private mvarTheaterMapFilename As String = "none"
    Private mvarTheaterMapScale As String = "1:1"
    Private mvarTurn As Int16
    Private mvarTurnLength As TurnLength_cgd
    Private mvarMaxTurns As Int16
    Private mvarUsesZOC As Boolean = False
    Private mvarSystemValues As New Hashtable   '// demo is saved in here, the other "demo" is a fake, item 221


    Private m_Moderator As ModeratorFlag = ModeratorFlag.ModeratorReady
    Private m_ModeratorPassword As String = ""
    Private m_ElManager As New ElementManager    ' handles specific elements defined in this game.
    Private m_ReinforcementRange As Int16 = 50
    Private m_AverageUnitMaxPV As Int32
    Private m_AverageObjectiveMaxPV As Int32
    Private m_MaxPointValueDeployed As Int32
    Private m_UseElementsForPointValues As Boolean = False ' if this is set to true, then element cost will determine a unit's PV
    Private m_UseElementsForMoveSpeed As Boolean = False
    Private m_UseElementsForMoveClass As Boolean = False
    Private m_UseElementsForLOSValues As Boolean = False
    Private m_AllowReinforcements As Boolean = True   ' whether the units within reinforcement range are used
    Private m_AllowPlayerManageChits As Boolean = False
    Private m_GenericBoundaries As New GenericBoundaries
    Private m_AreaObjectives As New GenericBoundaries
    Private m_ExtendedProperties As New GenericProperties
    Private m_OrderOfBattle As New Units
    Private m_CampaignDescription As String
    Private m_elapsedTime As New TimeSpan  '// the total elapsed game time
    Private m_remainingTime As New TimeSpan '// the remaining span for the turn, once it's 0, all rules and resources can be generated. Yah!

    Private _ForceOOB As Boolean = False
    Private _BGMPV As Integer = 0 '// if this is 0 there is no limit

    Private _replayPhaseKeys As New Hashtable '// it's 50xnumber of turns. 
    Private _replayPhaseKeysCol As New Collection

    Private _globalPhaseCount As Long    '// the total number of PHASES so far.
    Private _detectionEvents As New Hashtable

    '// added as of 1.8 "allchits" has gone the way of the dodo bird. Of course, he's reborn as _chits, rather phoenix-like.
    Private _chits As New ChitMembers  '// this holds all chits (installation and battlegroup)
    Private _localizeResources As Boolean = False  '// if true, resources work "locally" only, but can also be transported.
    Private _haltonNewDetection As Boolean
    Private _campaignEvents As New CampaignEvents    '// this will handle all the cool little events that occur during the campaign. Oh yah!
    Private _gameEndDetails As New EndGame
    Private _movementRate As movementRate_mr = movementRate_mr.hour_mr
    Private _elementTemplates As New Collection '// this holds all the created element templates. Easy peasy.

    Private _logevents As New Collection

    Private _combatEngagementRange As Integer = 16
    Private _cLabels As New CampaignerLabels

    Private _factionHistoricalPV
    Private _indicators As New Hashtable

    'Private _combatModule As combatengineidentifier



    Public Sub SetUpDataMapping()
        mvarSystemValues = New Hashtable

        Dim colMap() As String = {"C0C0FF", "FFFFFF", "B203D3", "0A03FF", "3D1FD3", "000000", "000000", "000000", "000000", "000000", "000000", "000000", "000000", "000000", "000000", "000000", "000000"}
        Dim moveMap() As Byte = { _
        134, 192, 82, 21, 222, 199, 148, 209, 103, 149, 61, 94, 208, 22, 179, 22, 99, 85, 182, 205, 117, 163, 206, 117, 123, 229, 73, 179, 51, 227, 89, 10, 215, 142, 149, 212, 34, 185, 83, 1, 11, 206, 172, 173, 150, 226, 220, 225, 212, 180, 110, 179, 185, 91, 207, 225, 240, 220, 153, 248, 125, 224, 158, 130, 60, 51, 133, 65, 128, 222, 242, 168, 2, 180, 194, 165, 245, 33, 221, 151, 8, 103, 221, 126, 117, 164, 79, 123, 190, 178, 226, 69, 31, 90, 131, 41, 48, 42, 113, 99, 93, 154, 97, 245, 192, 196, 177, 4, 152, 41, 235, 207, 253, 2, 239, 22, 2, 32, 12, 151, 226, 9, 130, 204, 250, 172, 137, 166, 49, 152, 117, 203, 174, 122, 57, 109, 5, 231, 188, 176, 241, 74, 226, 149, 198, 19, 71, 28, 106, 108, 39, 16, 30, 216, 127, 83, 24, 148, 249, 20, 59, 10, 210, 0, 178, 32, 32, 131, 200, 129, 16, 25, 98, 91, 165, 151, 38, 235, 5, 231, 101, 108, 60, 195, 113, 100, 172, 213, 249, 228, 84, 112, 237, 167, 116, 230, 119, 225, 225, 166, 241, 194, 83, 231, 92, 13, 172, 194, 51, 230, 45, 43, 142, 17, 174, 205, 205, 15, 142, 78, 114, 1, 74, 136, 226, 45, 159, 43, 185, 229, 189, 32, 67, 10, 93, 245, 161, 25, 83, 102, 99, 182, 233, 161, 18, 183, 40, 224, 219, 248, 166, 24, 103, 83, 147, 52}

        Dim dataMap() As Byte = { _
        129, 175, 169, 202, 190, 105, 136, 12, 167, 5, 92, 69, 175, 81, 90, 46, 135, 146, 78, 28, 237, 25, 91, 208, 108, 165, 171, 227, 18, 154, 195, 220, 75, 106, 191, 125, 187, 162, 29, 8, 90, 56, 253, 189, 120, 41, 72, 60, 18, 75, 171, 160, 169, 207, 88, 104, 83, 216, 93, 25, 189, 164, 249, 12, 65, 127, 249, 68, 144, 220, 114, 228, 117, 69, 193, 181, 26, 156, 87, 67, 92, 110, 208, 198, 237, 34, 50, 123, 18, 87, 41, 225, 69, 3, 74, 180, 62, 241, 124, 248, 47, 4, 170, 53, 215, 198, 43, 100, 14, 161, 78, 182, 129, 25, 188, 78, 211, 51, 29, 30, 76, 126, 49, 57, 179, 143, 159, 113, 249, 12, 119, 39, 31, 94, 19, 88, 195, 154, 237, 39, 245, 205, 108, 112, 9, 113, 96, 43, 70, 251, 224, 11, 211, 93, 171, 176, 209, 113, 129, 72, 38, 185, 105, 1, 42, 38, 151, 34, 6, 99, 137, 56, 68, 245, 39, 126, 17, 192, 47, 65, 47, 116, 43, 253, 43, 108, 83, 192, 177, 98, 133, 82, 25, 165, 0, 60, 100, 106, 70, 225, 217, 61, 36, 225, 113, 168, 197, 221, 53, 45, 158, 16, 65, 64, 24, 177, 141, 106, 213, 188, 210, 1, 213, 111, 162, 220, 55, 31, 158, 244, 233, 26, 166, 122, 77, 103, 240, 79, 72, 140, 130, 166, 116, 138, 132, 194, 116, 16, 216, 140, 78, 173, 248, 147, 136, 15}

        mvarSystemValues.Add("colormap", colMap)
        mvarSystemValues.Add("movemap", moveMap)
        mvarSystemValues.Add("datamap", datamap)

    End Sub

    'Public Property CombatModule() As CombatEngineIdentifier
    '    Get
    '        Return _combatModule
    '    End Get
    '    Set(ByVal value As CombatEngineIdentifier)
    '        _combatModule = value
    '    End Set
    'End Property

    Public Property Indicators() As Hashtable
        Get
            Return _indicators
        End Get
        Set(ByVal value As Hashtable)
            _indicators = value
        End Set
    End Property

    Public Property cLabels() As CampaignerLabels
        Get
            Return _cLabels
        End Get
        Set(ByVal value As CampaignerLabels)
            _cLabels = value
        End Set
    End Property

    Public Property combatEngagementRange() As Integer
        Get
            Return _combatEngagementRange
        End Get
        Set(ByVal value As Integer)
            _combatEngagementRange = value
        End Set
    End Property

    Public Property LogEvents() As Collection
        Get
            Return _logevents
        End Get
        Set(ByVal value As Collection)
            _logevents = value
        End Set
    End Property


    Public Property gameEndDetails() As EndGame
        Get
            Return _gameEndDetails
        End Get
        Set(ByVal value As EndGame)
            _gameEndDetails = value
        End Set
    End Property

    Public Property ReplayPhaseKeysCol() As Collection
        Get
            Return _replayPhaseKeysCol
        End Get
        Set(ByVal value As Collection)
            _replayPhaseKeysCol = value
        End Set
    End Property

    Public Property CampEvents() As CampaignEvents
        Get
            Return _campaignEvents
        End Get
        Set(ByVal value As CampaignEvents)
            _campaignEvents = value
        End Set
    End Property

    Public Property haltOnNewDetection() As Boolean
        Get
            Return _haltonNewDetection
        End Get
        Set(ByVal value As Boolean)
            _haltonNewDetection = value
        End Set
    End Property

    Public Property DetectionEvents() As Hashtable
        Get
            Return _detectionEvents
        End Get
        Set(ByVal value As Hashtable)
            _detectionEvents = value
        End Set
    End Property

    Public Property globalPhaseCount() As Long
        Get
            Return _globalPhaseCount
        End Get
        Set(ByVal value As Long)
            _globalPhaseCount = value
        End Set
    End Property

    Public Property ElapsedTime() As TimeSpan
        Get
            Return m_elapsedTime
        End Get
        Set(ByVal value As TimeSpan)
            m_elapsedTime = value
        End Set
    End Property

    Public Property remainingTime() As TimeSpan
        Get
            Return m_remainingTime
        End Get
        Set(ByVal value As TimeSpan)
            m_remainingTime = value
        End Set
    End Property

    Public Sub ResetRemainingTime()
        '// sets the remaining time to whatever it should tick down from... yahmon.
        Try
            Select Case TurnLength
                Case TurnLength_cgd.FiveMinute
                    '// with 50 turns, this is 6 seconds per phase 
                    m_remainingTime = New TimeSpan(0, 5, 0)
                Case TurnLength_cgd.FifteenMinute
                    '// with 50 turns, this is 18 seconds per phase (this info belongs in the combat engine... )
                    m_remainingTime = New TimeSpan(0, 15, 0)
                Case TurnLength_cgd.HalfHour
                    m_remainingTime = New TimeSpan(0, 30, 0)
                Case TurnLength_cgd.Hour
                    m_remainingTime = New TimeSpan(1, 0, 0)
                Case TurnLength_cgd.HalfDay
                    m_remainingTime = New TimeSpan(12, 0, 0)
                Case TurnLength_cgd.FullDay
                    m_remainingTime = New TimeSpan(1, 0, 0, 0)
                Case TurnLength_cgd.Week
                    m_remainingTime = New TimeSpan(7, 0, 0, 0)
                Case TurnLength_cgd.Month
                    m_remainingTime = New TimeSpan(30, 0, 0, 0)
            End Select

        Catch ex As Exception
            HandleException("CampaignerGameData", ex)
        End Try
    End Sub

#Region "Laziness Public Variables"
    ' HACK: all of this lazy junk should be moved to properties and proper collections
    Public Orders_g As New OrderTypes
    Public Faction_g As New Factions
    Public RuleTypes_g As New RuleTypes
    Public Rules_g As New Rules2
    Public ResourceTypes_g As New ResourceTypes
    Public Resources_g As New Resources
    Public Messages_g As New Messages
    Public DeploymentZones_g As New DeploymentZones
    Public Battles_g As New Battles
    Public Diplomacy_g As New Diplomacy
    Public MapLabels_g As New MapLabels
    Public ObjectiveTypes As New ObjectiveTypes_col
    Public UnitTypes As New UnitTypes_col 'Hashtable(10)
    Public TokenTypes As New Hashtable(10)
    Public selectedFaction As Faction
    Public selectedPlayer As Player
    Public SubObjectiveMaps As New SubObjectiveMaps
    Public Players As New Hashtable(2)
    '</laziness>   >:P
#End Region

#Region "Hashtable Key Constants"
    ' four letter key combinations for hashtable lookups
    Public Const CGDKEY_OBJECTIVETYPE As String = "OBJT"
    Public Const CDGKEY_RESOURCETYPE As String = "REST"
    Public Const CDGKEY_RULETYPE As String = "RULT"
    Public Const CDGKEY_UNITTYPE As String = "UNTT"
    Public Const CDGKEY_TOKENTYPE As String = "TOKT"

    Public Const CDGKEY_FACTION As String = "FACT"
    Public Const CDGKEY_PLAYER As String = "PLAY"

    Public Const CDGKEY_OBJECTIVE As String = "OBJE"
    Public Const CDGKEY_RESOURCE As String = "RESO"
    Public Const CDGKEY_RULE As String = "RULE"
    Public Const CDGKEY_UNIT As String = "UNIT"
    Public Const CDGKEY_TOKEN As String = "TOKN"
    Public Const CDGKEY_ASSIGNEDRULE As String = "ASRL"

    Public Const CDGKEY_ORDER As String = "ORDE"
    Public Const CDGKEY_ORDERTYPE As String = "ORDT"

    Public Const CDGKEY_BATTLE As String = "BATT"

    Public Const CDGKEY_CHITTYPE As String = "CHTT" ' generic chit... there shouldn't be many of these.
    Public Const CGDKEY_GROUNDCHITTYPE As String = "GCHT"  ' this is the main type that objective types, unit types and token types derive from.

    ' icon IDs for determining the correct display icon
    Public Const CDGDIP_OWNER As String = "Owner"
    Public Const CDGDIP_SAMEFACTION As String = "SameFaction"
    Public Const CDGDIP_ALLIED As String = "Allied"
    Public Const CDGDIP_NEUTRAL As String = "Neutral"
    Public Const CDGDIP_ENEMY As String = "Enemy"
#End Region

#Region "Data Sets"

    Public Sub SaveDataSet()
        ' this saves all type-specific data, such as chit types, resource types, etc as CGS file. Does not save game data.
        Dim sGame As New CampaignerGameData
        Dim setFileName As String

        ' not a valid option with a game marked as a demo

        Dim obj As Object = Me.SystemValue("datamap")
        If TypeOf obj Is String Then
            SetUpDataMapping()
            Throw New UnauthorizedAccessException
        Else
            Dim map() As Byte = obj
            If map(221) = 0 Then Throw New UnauthorizedAccessException
        End If

        'If Me.Demo Then
        '    Throw New UnauthorizedAccessException
        'End If

        Dim fs As New FileStream(setFileName, FileMode.CreateNew, FileAccess.ReadWrite, FileShare.ReadWrite)
        Dim bin As New BinaryFormatter

        Try
            sGame = Me.Clone

            ' delete map information
            With sGame
                .TheaterMapFilename = "none"
                .Battles_g.HT.Clear()
                .Chits.Clear()
                .DeploymentZones_g.HT.Clear()
                .Faction_g.HT.Clear()
                .GameName = setFileName
                .MapLabels_g.HT.Clear()
                .Messages_g.HT.Clear()
            End With

            bin.Serialize(fs, sGame)

        Catch
            Kill(setFileName)
            sGame = Me.Clone
            bin.Serialize(fs, sGame)
        Finally

        End Try
    End Sub

    Public Sub LoadDataSet(ByVal setFileName As String)
        'TODO: Loading Data Sets into a game.

    End Sub

#End Region

#Region "Property Declarations"

    Public Property Chits() As ChitMembers
        Get
            Return _chits
        End Get
        Set(ByVal value As ChitMembers)
            _chits = value
        End Set
    End Property

    Public Property BattlegroupMaxPointValue() As Integer
        Get
            Return _BGMPV
        End Get
        Set(ByVal value As Integer)
            _BGMPV = value
        End Set
    End Property

    Public Property ForceOOB() As Boolean
        Get
            Return _ForceOOB
        End Get
        Set(ByVal value As Boolean)
            _ForceOOB = value
        End Set
    End Property

    Public Property CampaignDescription() As String
        Get
            Return m_CampaignDescription
        End Get
        Set(ByVal Value As String)
            m_CampaignDescription = Value
        End Set
    End Property

    Public Property OrderOfBattle() As Units
        Get
            Return m_OrderOfBattle
        End Get
        Set(ByVal Value As Units)
            m_OrderOfBattle = Value
        End Set
    End Property

    Public Property Boundaries() As GenericBoundaries
        Get
            Return m_GenericBoundaries
        End Get
        Set(ByVal Value As GenericBoundaries)
            m_GenericBoundaries = Value
        End Set
    End Property

    Public Property AreaObjectives() As GenericBoundaries
        Get
            Return m_AreaObjectives
        End Get
        Set(ByVal Value As GenericBoundaries)
            m_AreaObjectives = Value
        End Set
    End Property

    Public Property ExtendedProperties() As GenericProperties
        Get
            Return m_ExtendedProperties
        End Get
        Set(ByVal Value As GenericProperties)
            m_ExtendedProperties = Value
        End Set
    End Property

    Public Property AllowReinforcements() As Boolean
        Get
            Return m_AllowReinforcements
        End Get
        Set(ByVal Value As Boolean)
            m_AllowReinforcements = Value
        End Set
    End Property

    Public Property UseElementsForPointValue() As Boolean
        Get
            Return m_UseElementsForPointValues
        End Get
        Set(ByVal Value As Boolean)
            m_UseElementsForPointValues = Value
        End Set
    End Property

    Public Property UseElementsForMoveSpeed() As Boolean
        Get
            Return m_UseElementsForMoveSpeed
        End Get
        Set(ByVal Value As Boolean)
            m_UseElementsForMoveSpeed = Value
        End Set
    End Property

    Public Property UseElementsForMoveClass() As Boolean
        Get
            Return m_UseElementsForMoveClass
        End Get
        Set(ByVal Value As Boolean)
            m_UseElementsForMoveClass = Value
        End Set
    End Property

    Public Property UseElementsForLOSValues() As Boolean
        Get
            Return m_UseElementsForLOSValues
        End Get
        Set(ByVal Value As Boolean)
            m_UseElementsForLOSValues = Value
        End Set
    End Property

    Public Property AllowPlayerManageChits() As Boolean
        Get
            Return m_AllowPlayerManageChits
        End Get
        Set(ByVal Value As Boolean)
            m_AllowPlayerManageChits = Value
        End Set
    End Property

    Public Property ElementMan() As ElementManager
        Get
            Return m_ElManager
        End Get
        Set(ByVal Value As ElementManager)
            m_ElManager = Value
        End Set
    End Property

    Public Function ReturnPlayerKeyWithID(ByVal id As Int64) As String
        Dim playkey As String
        Dim play As Player

        For Each playkey In Players.Keys
            play = Players.Item(playkey)
            If play.PlayerID = id Then
                Return playkey
            End If
        Next

        ' if we can't find the player with this id, raise an error
        Throw New ArgumentOutOfRangeException

    End Function

    Public Sub calculateMaxDeployedPV()
        Dim gc As GroundChitType
        Dim maxPV As Int32

        For Each mem As ChitMember In Chits
            If mem.UnitType = GroundChitClass_cgd.Battlegroup Then
                If maxPV < DirectCast(mem, BattlegroupChit).deployedpointvalue Then maxPV = DirectCast(mem, BattlegroupChit).deployedpointvalue
            End If
        Next

        'Return maxPV
        Me.m_MaxPointValueDeployed = maxPV
    End Sub

    Public ReadOnly Property DefinedManagableCount() As Int16
        Get
            ' returns the number of orders, objective types, token types, unit types, resource types and rule types defined
            Dim j As Int16
            j = ObjectiveTypes.Count + UnitTypes.Count + TokenTypes.Count + ResourceTypes_g.Count + RuleTypes_g.Count + Orders_g.Count
            Return j
        End Get
    End Property

    Public Property MaxPointValueDeployed() As Int32
        Get
            Return m_MaxPointValueDeployed
        End Get
        Set(ByVal Value As Int32)
            m_MaxPointValueDeployed = Value
        End Set
    End Property

    Public Property AverageUnitMaxPV() As Int32
        Get
            Return m_AverageUnitMaxPV
        End Get
        Set(ByVal Value As Int32)
            m_AverageUnitMaxPV = Value
        End Set
    End Property

    Public Property AverageObjectiveMaxPV() As Int32
        Get
            Return m_AverageObjectiveMaxPV
        End Get
        Set(ByVal Value As Int32)
            m_AverageObjectiveMaxPV = Value
        End Set
    End Property

    Public Property ModeratorPassword() As String
        Get
            Return m_ModeratorPassword
        End Get
        Set(ByVal Value As String)
            m_ModeratorPassword = Value
        End Set
    End Property

    Public Property Moderator() As ModeratorFlag
        Get
            Return m_Moderator
        End Get
        Set(ByVal Value As ModeratorFlag)
            m_Moderator = Value
        End Set
    End Property

    Public Property ReinforcementRange() As Int16
        Get
            'HACK: make this return the proper value
            Return 50
        End Get
        Set(ByVal Value As Int16)
            m_ReinforcementRange = Value
        End Set
    End Property

    '<Browsable(False)> Public Property Demo() As Boolean
    '    Get
    '        Return mvarDemo
    '    End Get
    '    Set(ByVal Value As Boolean)
    '        mvarDemo = Value
    '    End Set
    'End Property

    Public Property GameName() As String
        Get
            Return mvarGameName
        End Get
        Set(ByVal Value As String)
            mvarGameName = Value
        End Set
    End Property

    Public Property Version() As String
        Get
            Return mvarVersion
        End Get
        Set(ByVal Value As String)
            mvarVersion = Value
        End Set
    End Property

    Public Property TheaterMapFilename() As String
        Get
            Return mvarTheaterMapFilename
        End Get
        Set(ByVal Value As String)
            mvarTheaterMapFilename = Value
        End Set
    End Property

    Public Property TheaterMapScale() As String
        Get
            Return mvarTheaterMapScale
        End Get
        Set(ByVal Value As String)
            mvarTheaterMapScale = Value
        End Set
    End Property

    Public Property Turn() As Int16
        Get
            Return mvarTurn
        End Get
        Set(ByVal Value As Int16)
            mvarTurn = Value
        End Set
    End Property

    Public Property TurnLength() As TurnLength_cgd
        Get
            Return mvarTurnLength
        End Get
        Set(ByVal Value As TurnLength_cgd)
            mvarTurnLength = Value
        End Set
    End Property

    Public Property MaxTurns() As Int16
        Get
            Return mvarMaxTurns
        End Get
        Set(ByVal Value As Int16)
            mvarMaxTurns = Value
        End Set
    End Property

    Public Property UsesZOC() As Boolean
        Get
            Return mvarUsesZOC
        End Get
        Set(ByVal Value As Boolean)
            mvarUsesZOC = Value
        End Set
    End Property

    Public Property SystemValue(ByVal Key As String) As Object
        Get
            ' returns the item associated with the key or a "NoItem" return value
            Dim item As Object
            Try
                item = mvarSystemValues(Key)
                If item Is Nothing Then
                    Return "NoItem"
                Else
                    Return item
                End If
            Catch
                Return "NoItem"
            End Try
        End Get
        Set(ByVal Value As Object)
            ' updates or add the value with the associated key
            Try
                mvarSystemValues(Key) = Value
            Catch
                mvarSystemValues.Add(Key, Value)
            End Try
        End Set
    End Property

#End Region

#Region "File Operations"
    Public Sub Save(ByVal Filepath As String)
        ' serialize and save
        Dim sGame As New CampaignerGameData

        Try
            Dim fs As New FileStream(Filepath, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite)
            Dim bin As New BinaryFormatter

            sGame = Me.Clone

            bin.Serialize(fs, sGame)
        Catch ex As System.IO.IOException
            Kill(Filepath)
            Dim fs As New FileStream(Filepath, FileMode.CreateNew, FileAccess.ReadWrite, FileShare.ReadWrite)
            Dim bin As New BinaryFormatter

            sGame = Me.Clone
            bin.Serialize(fs, sGame)
        Catch ex As Exception
            Throw ex
        End Try
    End Sub

    Public Function Clone() As CampaignerGameData
        Dim m As New MemoryStream
        Dim b As New BinaryFormatter

        ' for the nonserializable junk
        Me.DeploymentZones_g.SetPathToPoints()
        Me.Boundaries.SetPathToPoints()
        Me.AreaObjectives.SetPathToPoints()

        b.Serialize(m, Me)
        m.Position = 0
        Return b.Deserialize(m)

    End Function

    Public Function Open(ByVal Filepath As String) As CampaignerGameData
        Dim fs As New FileStream(Filepath, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite)
        Dim bin As New BinaryFormatter
        Dim sGame As New CampaignerGameData

        sGame = CType(bin.Deserialize(fs), CampaignerGameData)

        ' for the nonserializable junk
        sGame.DeploymentZones_g.SetPointsToPath()
        sGame.Boundaries.SetPointsToPath()
        sGame.AreaObjectives.SetPointsToPath()
        ' make sure we have the current highest deployed point value
        SetToHighestDeployedPointValue()

        'If CType(sGame.Version, Integer) <> C_Version Then
        '    Update(sGame)
        'End If

        '// if someone is trying to open a demo game, with a non-demo software package (i.e. MINE) say NO.
        'If sGame.Demo = True Then
        '// not the place for this. This will be in the EXE. Yeah. Cuz... yeah.
        '#If MASTER = 1 Then
        '            MessageBox.Show("This is a DEMO campaign.", "Editing a demo", MessageBoxButtons.OK)
        '#Else
        '            MessageBox.Show("This is a demo campaign and can't be edited.", "Unable To Edit", MessageBoxButtons.OK)
        '            Return Nothing
        '#End If
        'End If

        Return sGame

    End Function

#Region "Update To Next Version"

    Private Function Update(ByRef sGame As CampaignerGameData) As Integer
        Dim ver As Single = CType(sGame.Version, Integer)

        Do Until ver = C_Version
            Select Case ver
                Case 0
                    ver = UpdateToV1(sGame)
                Case 1
                    ver = UpdateToV1_1(sGame)

            End Select
        Loop

        sGame.Version = ver

    End Function

    Private Function UpdateToV1(ByRef sGame As CampaignerGameData) As Single
        '// if we haven't updated the factions to faction14, lez do that.
        If Me.Faction_g.Count > 0 Then
            UpdateFactionsTo14()
        End If

        '// upgrade all ruletypes to resourceconsuming ruletypes
        UpdateConsumableResourceTypes(sGame)

        '// update orders
        UpdateOrders(sGame)

        Return 1

    End Function

    Private Function UpdateToV1_1(ByRef sGame As CampaignerGameData) As Single
        '// updates the battles to battle_2
        Dim batt As Battle
        Dim battKey As String
        Dim temporaryBattleList As New Collection '// holds the battles while the original is cleared

        Try
            For Each battKey In sGame.Battles_g.HT.Keys
                temporaryBattleList.Add(sGame.Battles_g.Item(battKey))
            Next

            sGame.Battles_g.HT.Clear()

            For Each batt In temporaryBattleList
                Dim bat2 As New Battle_2
                bat2.AttackerReady = batt.AttackerReady
                bat2.AttackerAssignedRules = batt.AttackerAssignedRules
                bat2.AttackingChitInitiative = batt.AttackingChitInitiative
                bat2.AttackingFactionID = batt.AttackingFactionID
                bat2.BattleID = batt.BattleID
                bat2.BattleLocation = batt.BattleLocation
                bat2.BattleName = batt.BattleName
                bat2.BattleResult = batt.BattleResult
                bat2.DefenderAssignedRules = batt.DefenderAssignedRules
                bat2.DefenderReady = batt.DefenderReady
                bat2.DefendingChitInitiative = batt.DefendingChitInitiative
                bat2.DefendingFactionID = batt.DefendingFactionID
                bat2.InvolvedChits = batt.InvolvedChits
                bat2.PhaseActive = batt.PhaseActive
                sGame.Battles_g.Add(bat2, bat2.Key)
            Next
            Return 1.1
        Catch ex As Exception
            HandleException("CampaignerGameData.UpdtateToV1_1", ex)
        End Try

    End Function

    Private Sub UpdateFactionsTo14()
        'Dim facKey As String
        'Dim fac As Object
        'Dim oldFac As Faction
        'Dim fac14 As Faction14
        'Dim remCol As New Collection

        'For Each facKey In Faction_g.HT.Keys
        '    fac = Faction_g.Item(facKey)
        '    If Not TypeOf fac Is Faction14 Then
        '        oldFac = fac
        '        fac14 = New Faction14
        '        With fac14
        '            ' detections...
        '            InsertDetections(fac14, oldFac)
        '            ' OOB
        '            InsertOOB(fac14, oldFac)
        '            ' victory conditions
        '            InsertVictoryConditions(fac14, oldFac)

        '            .ExtendedProperties = oldFac.ExtendedProperties
        '            .FactionDeployedPoints = oldFac.FactionDeployedPoints
        '            .FactionDescription = oldFac.FactionDescription
        '            .FactionID = oldFac.FactionID
        '            .FactionName = oldFac.FactionName
        '            .FactionTotalDeployedPoints = oldFac.FactionTotalDeployedPoints
        '            .FactionTotalPoints = oldFac.FactionTotalPoints
        '        End With
        '    End If
        '    ' now figure out what to do with the old ones... eh?
        '    '            Faction_g.HT.Remove(facKey)
        '    remCol.Add(facKey)
        'Next

        'Dim s As String
        'For Each s In remCol
        '    Faction_g.HT.Remove(s)
        'Next

    End Sub

    Private Sub UpdateConsumableResourceTypes(ByRef targetGame As CampaignerGameData)
        Dim item As Object
        Dim rults As RuleType
        Dim newConsumable As ResourceConsumingRuleType
        Dim rultKey As String
        Dim remcol As New Collection
        Dim tempCol As New Collection

        For Each rultKey In targetGame.RuleTypes_g.HT.Keys
            item = targetGame.RuleTypes_g.Item(rultKey)
            If Not TypeOf item Is ResourceConsumingRuleType Then
                rults = item
                Dim consumer As New ResourceConsumingRuleType
                With consumer
                    .AppliesDuring = rults.AppliesDuring
                    .BasicRange = rults.BasicRange
                    .CoreRule = rults.CoreRule
                    .MaxUses = rults.MaxUses
                    .RuleName = rults.RuleName
                    .RuleText = rults.RuleText
                    .RuleTypeID = rults.RuleTypeID
                End With
                remcol.Add(rultKey)
                tempCol.Add(consumer)
            End If
        Next

        '// remove the old
        For Each rultKey In remcol
            targetGame.RuleTypes_g.HT.Remove(rultKey)
        Next

        '// add the new
        For Each newConsumable In tempCol
            targetGame.RuleTypes_g.Add(newConsumable, newConsumable.Key)
        Next

    End Sub

    Private Sub UpdateOrders(ByRef targetGame As CampaignerGameData)

        '// clear all old orders
        targetGame.Orders_g.HT.Clear()

        Dim withord As New OrderType
        withord.OrderName = "Withdraw"
        withord.Description = "Withdraw from enemy contact."
        targetGame.Orders_g.Add(withord, withord.Key)

        Dim holdord As New OrderType
        holdord.OrderName = "Hold"
        holdord.Description = "Hold position when entering enemy ZOC."
        targetGame.Orders_g.Add(holdord, holdord.Key)

        Dim engageord As New OrderType
        engageord.OrderName = "Engage"
        engageord.Description = "Engage enemy forces."
        targetGame.Orders_g.Add(engageord, engageord.Key)

        Dim digord As New OrderType
        digord.OrderName = "Dig In"
        digord.Description = "Create defensive positions."
        targetGame.Orders_g.Add(digord, digord.Key)


    End Sub

    'Private Sub InsertDetections(ByRef fac14 As Faction14, ByRef oldFac As Faction)
    '    Dim detKey As String
    '    Dim det As ChitDetection

    '    For Each detKey In oldFac.HTChitDetection.Keys
    '        det = oldFac.HTChitDetection.Item(detKey)
    '        fac14.Detections.Add(det)
    '    Next

    'End Sub

    Private Sub InsertOOB(ByRef fac14 As Faction14, ByRef oldfac As Faction)
        Dim gc As GroundChitType

        For Each gc In oldfac.OrderOfBattle
            fac14.OrderOfBattle.add(gc)
        Next

    End Sub

    Private Sub InsertVictoryConditions(ByRef fac14 As Faction14, ByRef oldfac As Faction)
        Dim vc As IVictoryCondition

        For Each vc In oldfac.FactionVictoryConditions
            fac14.FactionVictoryConditions.Add(vc)
        Next
    End Sub

#End Region

    Public Function ImportTemplate(ByVal Filepath As String) As Boolean
        ' imports a template of everything but a map.
        Dim impCGD As New CampaignerGameData

        Try
            impCGD = impCGD.Open(Filepath)
            ' here we begin the import
            ImportRules(impCGD)
            ImportResources(impCGD)
            ImportOrders(impCGD)
            ImportChits(impCGD)
        Catch ex As Exception
            HandleException("Campaigner Game Data Import Template", ex)
        End Try

    End Function

    Public Function ExportTemplate(ByVal Filepath As String) As Boolean
        ' exports to a template file

    End Function

#End Region

#Region "Import Template"
    Private Function ImportRules(ByRef source As CampaignerGameData) As Boolean
        ' A *.cgd or *.cgt file may be used for importing (campaigner game data, campaigner game template)
        Dim rult As RuleType
        Dim rulkey As String

        For Each rulkey In source.RuleTypes_g.HT.Keys
            rult = source.RuleTypes_g.Item(rulkey)
            Dim newRule As New RuleType
            With newRule
                .AppliesDuring = rult.AppliesDuring
                .BasicRange = rult.BasicRange
                .CoreRule = rult.CoreRule
                .MaxUses = rult.MaxUses
                .RuleName = rult.RuleName
                .RuleText = rult.RuleText
            End With

            Dim done As Boolean = False
            Do Until done
                Try
                    ' try to add this guy
                    RuleTypes_g.Add(newRule, newRule.Key)
                    done = True
                Catch argex As System.ArgumentException
                    newRule.BoostMCID()
                    done = False
                Catch ex As Exception
                    HandleException("Campaigner Game Data ImportRules", ex)
                    Return False
                End Try
            Loop
        Next

        Return True

    End Function

    Private Function ImportResources(ByRef source As CampaignerGameData) As Boolean
        Dim resT As ResourceType
        Dim resKey As String

        For Each resKey In source.ResourceTypes_g.HT.Keys
            resT = source.ResourceTypes_g.Item(resKey)
            Dim newRest As New ResourceType

            With newRest
                .ResourceDescription = resT.ResourceDescription
                .ResourceName = resT.ResourceName
            End With

            Dim done As Boolean = False
            Do Until done
                Try
                    ResourceTypes_g.Add(newRest, newRest.Key)
                    done = True
                Catch argex As System.ArgumentException
                    newRest.BoostMCID()
                    done = False
                Catch ex As Exception
                    HandleException("Campaigner Game Data ImportResources", ex)
                    done = True
                    Return False
                End Try
            Loop
        Next
    End Function

    Private Function ImportOrders(ByRef source As CampaignerGameData) As Boolean
        Dim ord As OrderType
        Dim ordKey As String

        For Each ordKey In source.Orders_g.HT.Keys
            ord = source.Orders_g.Item(ordKey)
            Dim newOrd As New OrderType
            With newOrd
                .Description = ord.Description
                .OrderFlag = ord.OrderFlag
                .OrderName = ord.OrderName
            End With

            Dim done As Boolean = False
            Do Until done
                Try
                    Orders_g.Add(newOrd, newOrd.Key)
                    done = True
                Catch argex As ArgumentException
                    newOrd.BoostMCID()
                    done = False  ' here of course, for clarity
                Catch ex As Exception
                    HandleException("Campaigner Game Data ImportOrders", ex)
                    done = True
                    Return False
                End Try
            Loop
        Next

    End Function

    Private Function ImportChits(ByRef source As CampaignerGameData) As Boolean
        Try
            ImportObjectiveTypes(source)
        Catch ex As Exception
            HandleException("Campaigner Game Data ImportChits", ex)
        End Try

        Try
            ImportUnitTypes(source)
        Catch ex As Exception
            HandleException("Campaigner Game Data ImportChits", ex)
        End Try

        Try
            ImportTokenTypes(source)
        Catch ex As Exception
            HandleException("Campaigner Game Data ImportChits", ex)
        End Try
    End Function

    Private Function ImportObjectiveTypes(ByRef source As CampaignerGameData) As Boolean
        Dim objt As ObjectiveType
        'Dim objKey As String

        For Each objt In source.ObjectiveTypes
            '   objt = source.ObjectiveTypes.Item(objKey)
            Dim newObj As ObjectiveType = objt.Clone
            Dim done As Boolean

            Do Until done
                Try
                    ObjectiveTypes.add(newObj)
                    done = True
                Catch argEx As ArgumentException
                    newObj.BoostMCID()
                    done = False
                Catch ex As Exception
                    HandleException("Campaigner Game Data ImportObjectiveTypes", ex)
                    done = True
                    Return False
                End Try
            Loop
            done = False
        Next

    End Function

    Private Function ImportUnitTypes(ByRef source As CampaignerGameData) As Boolean
        Dim unitT As UnitType
        'Dim unitKey As String

        For Each unitT In source.UnitTypes
            'unitT = source.UnitTypes.Item(unitKey)
            Dim newUnit As UnitType = unitT.Clone
            Dim done As Boolean = False

            Do Until done
                Try
                    UnitTypes.add(newUnit)
                    done = True
                Catch exArg As ArgumentException
                    newUnit.BoostMCID()
                    done = False
                Catch ex As Exception
                    HandleException("Campaigner Game Data ImportUnitTypes", ex)
                    done = True
                    Return False
                End Try
            Loop
        Next

    End Function

    Private Function ImportTokenTypes(ByRef source As CampaignerGameData) As Boolean
        Dim tokT As TokenType
        Dim tokKey As String

        For Each tokKey In source.TokenTypes.Keys
            'tokT = source.TokenTypes.Item(tokKey)
            'Dim newTok As TokenType = tokT.Clone
            'Dim done As Boolean

            'Do Until done
            '    Try
            '        TokenTypes.Add(newTok.Key, newTok)
            '        done = True
            '    Catch exArg As ArgumentException
            '        newTok.BoostMCID()
            '        done = False
            '    Catch ex As Exception
            '        HandleException("Campaigner Game Data ImportTokenTypes", ex)
            '        done = True
            '        Return False
            '    End Try
            'Loop
        Next

    End Function

#End Region

    Private Sub SetToHighestDeployedPointValue()
        'Dim unKey As String
        'Dim gc As GroundChitType
        'Dim uni As UnitType

        m_MaxPointValueDeployed = 0

        Dim mem As ChitMember
        For Each mem In _chits
            If mem.UnitType <> GroundChitClass_cgd.Objective Then
                '// these should ALL be battlegroups, you can't have a floating chitunittypemember in here.
                If DirectCast(mem, BattlegroupChit).CurrentPV > m_MaxPointValueDeployed Then m_MaxPointValueDeployed = DirectCast(mem, BattlegroupChit).CurrentPV
            End If
        Next

        'For Each unKey In AllChits.Keys
        '    gc = AllChits.Item(unKey)
        '    If gc.GroundChitClass = GroundChitClass_cgd.Unit Then
        '        uni = gc
        '        If uni.CurrentPointValue > m_MaxPointValueDeployed Then m_MaxPointValueDeployed = uni.CurrentPointValue
        '    End If
        'Next

    End Sub

    Public Function TextForLOSPower(ByVal losPower As Single) As String
        Select Case losPower
            Case Is >= 150 : Return "Weak"
            Case Is >= 120 : Return "Low"
            Case Is >= 100 : Return "Average"
            Case Is >= 80 : Return "Good"
            Case Is >= 60 : Return "Strong"
            Case Is >= 50 : Return "Powerful"
            Case Is >= 30 : Return "Very Powerful"
            Case Else
                Return "Unknown"
        End Select
    End Function

    Public Function TextForSize(ByVal size As Single) As String
        Select Case size
            Case Is <= 5 : Return "Tiny"
            Case Is <= 10 : Return "Very Small"
            Case Is <= 25 : Return "Slight"
            Case Is <= 50 : Return "Small"
            Case Is <= 100 : Return "Average"
            Case Is <= 200 : Return "Big"
            Case Is <= 400 : Return "Large"
            Case Is <= 600 : Return "Immense"
            Case Is <= 1000 : Return "Huge"
            Case Is <= 1500 : Return "Massive"
            Case Else
                Return "Titanic"
        End Select
    End Function

    Public Sub New()
        '// set up our datamaps in system data
        setupdatamapping()
    End Sub

    
End Class

' other classes

Public Class CampaignerItemTreeNode
    Inherits TreeNode

    Private m_Item As Object
    Private m_ItemType As CampaignerItem_cgd

    Public Property Item() As Object
        Get
            Return m_Item
        End Get
        Set(ByVal Value As Object)
            m_Item = Value
        End Set
    End Property

    Public Property ItemType() As CampaignerItem_cgd
        Get
            Return m_ItemType
        End Get
        Set(ByVal Value As CampaignerItem_cgd)
            m_ItemType = Value
        End Set
    End Property

End Class

#Region "Sub-Objective Maps"

<Serializable()> Public Class SubObjectiveMap
    Shared m_SubMapID As Int16
    Public m_ID As Int16
    Private m_Location As Point
    Private m_Filename As String
    Private m_Width As Int16
    Private m_Height As Int16
    Private m_Scale As String

    Public Sub New()
        m_SubMapID += 1
        m_ID = m_SubMapID
    End Sub

#Region "Properties"
    Public ReadOnly Property SubMapID() As Int16
        Get
            Return m_ID
        End Get
    End Property

    Public Property Location() As Point
        Get
            Return m_Location
        End Get
        Set(ByVal Value As Point)
            m_Location = Value
        End Set
    End Property

    Public Property FileName() As String
        Get
            Return m_Filename
        End Get
        Set(ByVal Value As String)
            m_Filename = Value
        End Set
    End Property

    Public Property Width() As Int16
        Get
            Return m_Width
        End Get
        Set(ByVal Value As Int16)
            m_Width = Value
        End Set
    End Property

    Public Property Height() As Int16
        Get
            Return m_Height
        End Get
        Set(ByVal Value As Int16)
            m_Height = Value
        End Set
    End Property

    Public Property Scale() As String
        Get
            Return m_Scale
        End Get
        Set(ByVal Value As String)
            m_Scale = Value
        End Set
    End Property
#End Region

End Class

<Serializable()> Public Class SubObjectiveMaps
    ' a collection of sub objective maps
    Private mCol As New Hashtable

    Public Function Item(ByVal sKey As String) As DeploymentZone
        Try
            Return mCol(sKey)
        Catch
            Debug.WriteLine("Could not find item '" & sKey & "' in DeploymentZones Collection.")
            Return Nothing
        End Try
    End Function

    Public Sub Add(ByVal Item As DeploymentZone, ByVal sKey As String)
        mCol.Add(sKey, Item)
    End Sub

    Public ReadOnly Property HT() As Hashtable
        Get
            Return mCol
        End Get
    End Property

End Class

#End Region

#Region "Element and Option Rules"
' these are for making rules applying Options to Elements... whoa. Bigger than I anticipated.

Public Interface ElementConstructionRule
    Property ElementTypeName() As String
    Property ElementOptionRestriction() As Boolean
    Property ElementCountRestriction() As Boolean

End Interface

<Serializable()> Public Class ElementTypeOptionRule
    Private m_ElementTypeName As String
    Private m_OptionName As String
    Private m_MaxOptionCount As Integer
    Private m_MinOptionCount As Integer


End Class

#End Region

#Region "Chits"

<Serializable()> Public MustInherit Class ChitType

    Shared mvarCID As Int32
    Private mvarID As Int32
    Private mvarMapID As Int16
    Private mvarLocation As Point
    Private mvarName As String
    Private mvarDescription As String
    Private mvarIcons As New Hashtable(5)   ' Icons are: Owner, SameFaction, Allied, Neutral, Enemy
    Private mvarOwningFaction As Int64 = 0
    Private mvarOwningPlayer As Int64 = 0
    Private mvarExtendedProperties As New GenericProperties
    Private mvarInitialPointValue As Single = 0
    Private mvarCurrentPointValue As Int64 = 0
    Private mvarElements As New GroupableElements   ' yeah. Anything can have elements, since they can be ... anything.
    Private mvarUseElementsForPointValue As Boolean = False   ' used when a player marks the check on deployment
    Private mvarTreeNode As New TreeNode

    Private _elements As New Hashtable  '// THIS is the real elements table. All previous element stuff is false. This is the one true elements list.
    Private _attributes As New Collection


    Public Sub New()
        mvarIcons.Add("Owner", New Bitmap(16, 16))
        mvarIcons.Add("SameFaction", New Bitmap(16, 16))
        mvarIcons.Add("Allied", New Bitmap(16, 16))
        mvarIcons.Add("Neutral", New Bitmap(16, 16))
        mvarIcons.Add("Enemy", New Bitmap(16, 16))
        mvarCID += 1  ' increment the shared group id counter
        mvarID = mvarCID
    End Sub

    Public Overridable Function AsTreeNode() As TreeNode
        Return mvarTreeNode
    End Function

    Public Overridable Function PropertiesToTreeView() As System.Windows.Forms.TreeNodeCollection
        ' returns a treenode collection of its properties
        Dim nodeCol As System.Windows.Forms.TreeNodeCollection

        nodeCol.Add("Name: " & mvarName)
        nodeCol.Add("X: " & mvarLocation.X.ToString)
        nodeCol.Add("Y: " & mvarLocation.Y.ToString)

        Return nodeCol

    End Function

    Public Property ChitAttributes() As Collection
        Get
            If _attributes Is Nothing Then _attributes = New Collection
            Return _attributes
        End Get
        Set(ByVal value As Collection)
            _attributes = value
        End Set
    End Property

    Public Sub BoostMCID()
        ' used to boost up the member class id, and the member id
        mvarCID += 5
        mvarID += 5
    End Sub

    <Browsable(False)> Public Overridable ReadOnly Property Key() As String
        Get
            Return CStr(cmplib01.CampaignerGameData.CDGKEY_CHITTYPE & mvarID)
        End Get
    End Property

    <Browsable(False)> Public ReadOnly Property [ID]() As Int16
        Get
            Return mvarID
        End Get
    End Property

    <Browsable(False)> Public Property MapID() As Int16
        Get
            Return mvarMapID
        End Get
        Set(ByVal Value As Int16)
            mvarMapID = Value
        End Set
    End Property

    <Browsable(False)> Public Property Location() As Point
        Get
            Return mvarLocation
        End Get
        Set(ByVal Value As Point)
            mvarLocation = Value
        End Set
    End Property

    <Browsable(False)> Public Property [Name]() As String
        Get
            Return mvarName
        End Get
        Set(ByVal Value As String)
            mvarName = Value
            mvarTreeNode.Text = mvarName
        End Set
    End Property

    <Category("Builder")> Public Property Description() As String
        Get
            Return mvarDescription
        End Get
        Set(ByVal Value As String)
            mvarDescription = Value
        End Set
    End Property

    <Browsable(False)> Public Property Icon(ByVal key As String) As Bitmap
        Get
            Return mvarIcons(key)
        End Get
        Set(ByVal Value As Bitmap)
            mvarIcons(key) = Value
        End Set
    End Property

    <Browsable(False)> Public Property OwningFaction() As Int64
        Get
            Return mvarOwningFaction
        End Get
        Set(ByVal Value As Int64)
            mvarOwningFaction = Value
        End Set
    End Property

    <Browsable(False)> Public Property OwningPlayer() As Int64
        Get
            Return mvarOwningPlayer
        End Get
        Set(ByVal Value As Int64)
            mvarOwningPlayer = Value
        End Set
    End Property

    <Browsable(False)> Public Property ExtendedProperties() As GenericProperties
        Get
            Return mvarExtendedProperties
        End Get
        Set(ByVal Value As GenericProperties)
            mvarExtendedProperties = Value
        End Set
    End Property

    <Browsable(False)> Public Property InitialPointValue() As Single
        Get
            Return mvarInitialPointValue
        End Get
        Set(ByVal Value As Single)
            mvarInitialPointValue = Value
        End Set
    End Property

    <Browsable(False)> Public Property CurrentPointValue() As Int64
        Get
            Return mvarCurrentPointValue
        End Get
        Set(ByVal Value As Int64)
            mvarCurrentPointValue = Value
        End Set
    End Property

    <Browsable(False)> Public Property ChitElements() As GroupableElements
        Get
            Return mvarElements
        End Get
        Set(ByVal Value As GroupableElements)
            mvarElements = Value
        End Set
    End Property

    <Browsable(False)> Public Property UseElementsForPointValue() As Boolean
        Get
            Return mvarUseElementsForPointValue
        End Get
        Set(ByVal Value As Boolean)
            mvarUseElementsForPointValue = Value
        End Set
    End Property

    <Browsable(True)> Public Property Elements() As Hashtable
        Get
            Return _elements
        End Get
        Set(ByVal value As Hashtable)
            _elements = value
        End Set
    End Property

End Class


<Serializable()> Public MustInherit Class GroundChitType
    ' Status has been moved here for combat purposes.
    ' added battle result also.
    Inherits ChitType

    Shared mvarCID As Int32
    Private mvarTypeID As Int32
    Private mvarTypeName As String
    Private mvarLOS As Single = 5
    Private mvarLOSPower As Int16 = 100
    Private mvarSize As Int16 = 100
    Private mvarUsesZOC As Boolean = False
    Private mvarZOCRange As Single = 0
    Private mvarGroundChitClass As GroundChitClass_cgd
    <NonSerialized()> Private mvarCurrentTerrainName As String
    <NonSerialized()> Private mvarDetectedThisTurn As Boolean = False
    Private mvarBattleInvolvedInID As Int16 ' this points to the combat this ground chit is involved in
    Private mvarHistoricalLocation As New ArrayList(10)
    Private mvarCurrentBattlePosture As BattlePosture_cgd = BattlePosture_cgd.NoBattle
    Private mvarStatus As GroundUnitStatus_cgd
    Private mvarBattleresult As UnitBattleResult_cgd
    Private mvarElements As GroupableElements
    Private mvarElementClassID As Integer = -1 ' default of none
    Private mvarRules2 As New Rules2   ' so all ground chits can have rules. Sigh. Yup. All of them.

    Private _transportedunits As New GroundChits '// lists what we're carrying.
    Private _transportingIn As GroundChitType   '// if we're being transported, this is who we're riding in... 
    Private _transportCapacity As Integer   ' the amount of transport stuff this guy can do
    Private _transportCost As Integer      ' the cost associated with transporting this guy
    Private _canbetransported As Boolean
    Private _cantransport As Boolean

    <NonSerialized()> Private mvarEffectiveLOSRange As Integer    ' after movement orders or other modifiers (not saved, combat engine uses this). Modified for pixels
    <NonSerialized()> Private mvarEffectiveLOSPower As Integer
    <NonSerialized()> Private mvarEffectiveSpeed As Integer ' modified for pixels
    <NonSerialized()> Private mvarEffectiveZOC As Integer ' modified for pixels
    <NonSerialized()> Private mvarTotalDistanceMovedThisTurn As Single ' measured in MILES.
    <NonSerialized()> Private mvarInvalidWaypoint As Boolean = False
    <NonSerialized()> Private _node As New TreeNode
    <NonSerialized()> Public DistanceTravelled As Single

    Private _indicators As New Hashtable


    Public Sub New()
        mvarCID += 1
        mvarTypeID = mvarCID
        _node = New TreeNode
        _node.Tag = Me
    End Sub

    Public Property Indicators() As Hashtable
        Get
            Return _indicators
        End Get
        Set(ByVal value As Hashtable)
            _indicators = value
        End Set
    End Property

    <Browsable(False)> Public Property Node() As TreeNode
        Get
            Return _node
        End Get
        Set(ByVal value As TreeNode)
            _node = value
        End Set
    End Property

    <Browsable(False)> Public Property TransportedUnits() As GroundChits
        Get
            Return _transportedunits
        End Get
        Set(ByVal Value As GroundChits)
            _transportedunits = Value
        End Set
    End Property

    <Browsable(False)> Public Property TransportingIn() As GroundChitType
        Get
            Return _transportingIn
        End Get
        Set(ByVal Value As GroundChitType)
            _transportingIn = Value
        End Set
    End Property

    <Category("Builder")> Public Overridable Property CanTransport() As Boolean
        Get
            Return _cantransport
        End Get
        Set(ByVal Value As Boolean)
            _cantransport = Value
        End Set
    End Property

    <Category("Builder")> Public Overridable Property CanBeTransported() As Boolean
        Get
            Return _canbetransported
        End Get
        Set(ByVal Value As Boolean)
            _canbetransported = Value
        End Set
    End Property

    <Category("Builder")> Public Property TransportCapacity() As Integer
        Get
            Return _transportCapacity
        End Get
        Set(ByVal Value As Integer)
            _transportCapacity = Value
        End Set
    End Property

    <Category("Builder")> Public Overridable Property TransportCost() As Integer
        Get
            Return _transportCost
        End Get
        Set(ByVal Value As Integer)
            _transportCost = Value
        End Set
    End Property

    Public Overrides Function ToString() As String
        If MyBase.Name = "" Then
            Return mvarTypeName
        Else
            Return MyBase.Name
        End If

    End Function

    <Browsable(False)> Public Property GCRules() As Rules2
        ' uses improved rules collection. Its really fab baby.
        Get
            Return mvarRules2

        End Get
        Set(ByVal Value As Rules2)
            mvarRules2 = Value

        End Set
    End Property

    <Browsable(False)> Public Property InvalidWaypoint() As Boolean
        Get
            Return mvarInvalidWaypoint
        End Get
        Set(ByVal Value As Boolean)
            mvarInvalidWaypoint = Value
        End Set
    End Property

    <Browsable(False)> Public Property TotalDistanceMovedThisTurn() As Single
        Get
            Return mvarTotalDistanceMovedThisTurn
        End Get
        Set(ByVal Value As Single)
            mvarTotalDistanceMovedThisTurn = Value
        End Set
    End Property

    <Browsable(False)> Public Property EffectiveLOSRange() As Integer
        Get
            Return mvarEffectiveLOSRange
        End Get
        Set(ByVal Value As Integer)
            mvarEffectiveLOSRange = Value
        End Set
    End Property

    <Browsable(False)> Public Property EffectiveLOSPower() As Integer
        Get
            Return mvarEffectiveLOSPower
        End Get
        Set(ByVal Value As Integer)
            mvarEffectiveLOSPower = Value
        End Set
    End Property

    <Browsable(False)> Public Property EffectiveSpeed() As Integer
        Get
            Return mvarEffectiveSpeed
        End Get
        Set(ByVal Value As Integer)
            mvarEffectiveSpeed = Value
        End Set
    End Property

    <Browsable(False)> Public Property EffectiveZOC() As Integer
        Get
            Return mvarEffectiveZOC
        End Get
        Set(ByVal Value As Integer)
            mvarEffectiveZOC = Value
        End Set
    End Property

    <Browsable(False)> Public Property CurrentTerrainName() As String
        Get
            'used as a temporary holder
            Return mvarCurrentTerrainName
        End Get
        Set(ByVal Value As String)
            mvarCurrentTerrainName = Value
        End Set
    End Property

    <Browsable(False)> Public Property Status() As GroundUnitStatus_cgd
        Get
            Return mvarStatus
        End Get
        Set(ByVal Value As GroundUnitStatus_cgd)
            mvarStatus = Value
        End Set
    End Property

    <Browsable(False)> Public Property BattleResult() As UnitBattleResult_cgd
        Get
            Return mvarBattleresult
        End Get
        Set(ByVal Value As UnitBattleResult_cgd)
            mvarBattleresult = Value
        End Set
    End Property

    <Browsable(False)> Public Overridable Property CurrentBattlePosture() As BattlePosture_cgd
        Get
            Return mvarCurrentBattlePosture
        End Get
        Set(ByVal Value As BattlePosture_cgd)
            mvarCurrentBattlePosture = Value
        End Set
    End Property

    <Browsable(False)> Public Overridable Property BattleInvolvedInID() As Int16
        Get
            Return mvarBattleInvolvedInID
        End Get
        Set(ByVal Value As Int16)
            mvarBattleInvolvedInID = Value
        End Set
    End Property

    <Browsable(False)> Public Property DetectedThisTurn() As Boolean
        Get
            Return mvarDetectedThisTurn
        End Get
        Set(ByVal Value As Boolean)
            mvarDetectedThisTurn = Value
        End Set
    End Property

    <Browsable(False)> Public Property HistoricalLocation() As ArrayList
        Get
            Return mvarHistoricalLocation
        End Get
        Set(ByVal Value As ArrayList)
            mvarHistoricalLocation = Value
        End Set
    End Property

    <Browsable(False)> Public Overrides ReadOnly Property Key() As String
        Get
            Return cmplib01.CampaignerGameData.CGDKEY_GROUNDCHITTYPE & mvarTypeID.ToString
        End Get
    End Property

    <Browsable(False)> Public Property TypeID() As Int16
        Get
            Return mvarTypeID
        End Get
        Set(ByVal value As Int16)
            mvarTypeID = value
        End Set
    End Property

    <Category("Builder")> Public Property TypeName() As String
        Get
            Return mvarTypeName
        End Get
        Set(ByVal Value As String)
            mvarTypeName = Value
            If _node Is Nothing Then _node = New TreeNode
            _node.Text = Value
        End Set
    End Property

    <Category("Builder")> Public Property LOS() As Single
        Get
            Return mvarLOS
        End Get
        Set(ByVal Value As Single)
            mvarLOS = Value
        End Set
    End Property

    <Category("Builder")> Public Property LOSPower() As Int16
        Get
            Return mvarLOSPower
        End Get
        Set(ByVal Value As Int16)
            mvarLOSPower = Value
        End Set
    End Property

    <Category("Builder")> Public Property Size() As Int16
        Get
            Return mvarSize
        End Get
        Set(ByVal Value As Int16)
            mvarSize = Value
        End Set
    End Property

    <Category("Builder")> Public Property UsesZOC() As Boolean
        Get
            Return mvarUsesZOC
        End Get
        Set(ByVal Value As Boolean)
            mvarUsesZOC = Value
        End Set
    End Property

    <Category("Builder")> Public Property ZOCRange() As Single
        Get
            Return mvarZOCRange
        End Get
        Set(ByVal Value As Single)
            mvarZOCRange = Value
        End Set
    End Property

    <Browsable(False)> Public Property GroundChitClass() As GroundChitClass_cgd
        Get
            Return mvarGroundChitClass
        End Get
        Set(ByVal Value As GroundChitClass_cgd)
            mvarGroundChitClass = Value
        End Set
    End Property

End Class

#Region "Indicators"

<Serializable()> Public Enum IndicatorType_enum
    value = 1
    named = 2
    namedvalue = 3
End Enum

Public Interface IIindciator
    ReadOnly Property IndicatorType() As IndicatorType_enum
    Property IndicatorName() As String
    ReadOnly Property IsSystem() As Boolean
    Function CreateEntry() As cmplib01.IIndicatorEntry

End Interface


<Serializable()> Public MustInherit Class Indicator : Implements IIindciator
    Private _indicatorName As String
    Private _IsSystem As Boolean = False

    Public MustOverride ReadOnly Property IndicatorType() As IndicatorType_enum Implements IIindciator.IndicatorType
    Public MustOverride Function CreateEntry() As IIndicatorEntry Implements IIindciator.CreateEntry

    Public Property IndicatorName() As String Implements IIindciator.IndicatorName
        Get
            Return _indicatorName
        End Get
        Set(ByVal value As String)
            _indicatorName = value
        End Set
    End Property

    Public ReadOnly Property IsSystem() As Boolean Implements IIindciator.IsSystem
        Get
            Return _IsSystem
        End Get
    End Property

End Class


<Serializable()> Public Class ValueIndicator : Inherits Indicator
    '// Value indicator properties
    'Private _indicatorValue As Single
    Private _indicatorMinimum As Single = 0
    Private _indicatorMaximum As Single = 100
    Private _defaultValue As Single = 50

    Public Overrides Function ToString() As String
        Return MyBase.IndicatorName
    End Function

    Public Function Validate(ByVal value As Single) As Single

        If value > _indicatorMaximum Then value = _indicatorMaximum
        If value < _indicatorMinimum Then value = _indicatorMinimum

        Return value

    End Function

    Public Overrides Function CreateEntry() As IIndicatorEntry
        Dim vindicator As New ValueIndicatorEntry
        vindicator.ptrIndicator = Me
        vindicator.Value = Me.defValue

        Return vindicator
    End Function

    <Browsable(True)> Public Property Minimum() As Single
        Get
            Return _indicatorMinimum
        End Get
        Set(ByVal value As Single)
            _indicatorMinimum = value
        End Set
    End Property

    <Browsable(True)> Public Property Maximum() As Single
        Get
            Return _indicatorMaximum
        End Get
        Set(ByVal value As Single)
            _indicatorMaximum = value
        End Set
    End Property

    <Browsable(True)> Public Property defValue() As Single
        Get
            Return _defaultValue
        End Get
        Set(ByVal value As Single)
            _defaultValue = value
        End Set
    End Property

    Public Overrides ReadOnly Property IndicatorType() As IndicatorType_enum
        Get
            Return IndicatorType_enum.value
        End Get
    End Property
End Class


<Serializable()> Public Class NamedIndicator : Inherits Indicator

    Private _names As New Collection
    Private _defaultname As String = "none"


    Public Overrides Function CreateEntry() As IIndicatorEntry
        Dim nindicator As New NamedIndicatorEntry
        _defaultname = _names.Item(1)
        nindicator.ptrIndicator = Me
        nindicator.name = _defaultname

        Return nindicator
    End Function

    Public Overrides Function ToString() As String
        Return MyBase.IndicatorName
    End Function

    Public Property DefaultName() As String
        Get
            Return _defaultname
        End Get
        Set(ByVal value As String)
            _defaultname = value
        End Set
    End Property

    Public Overrides ReadOnly Property IndicatorType() As IndicatorType_enum
        Get
            Return IndicatorType_enum.named
        End Get
    End Property

    <Browsable(True)> Public Property names() As Collection
        Get
            Return _names
        End Get
        Set(ByVal value As Collection)
            _names = value
        End Set
    End Property

    Public Function Validate(ByVal value As String) As String
        '// we just need to verify the requested value exits
        Try
            If _names.Contains(value) Then Return value '// a-ok
            Return "none"
        Catch ex As Exception
            Return "none"
        End Try
    End Function

End Class


<Serializable()> Public Class NamedValueIndicator : Inherits Indicator

    Private _items As New Hashtable '// key is the name, object is the value
    Private _defaultname As String = "none"

    Public Overrides Function CreateEntry() As IIndicatorEntry
        Dim nvindicator As New NamedValueIndicatorEntry
        Dim key As String
        For Each k As String In _items.Keys
            key = k
            Exit For
        Next
        _defaultname = key
        nvindicator.ptrIndicator = Me
        nvindicator.Name = Me.DefaultName
        Return nvindicator
    End Function

    Public Overrides Function ToString() As String
        Return MyBase.IndicatorName
    End Function

    Public Property DefaultName() As String
        Get
            Return _defaultname
        End Get
        Set(ByVal value As String)
            _defaultname = value
        End Set
    End Property

    Public Overrides ReadOnly Property IndicatorType() As IndicatorType_enum
        Get
            Return IndicatorType_enum.namedvalue
        End Get
    End Property

    Public Sub ClearItems()
        _items.Clear()
    End Sub

    <Browsable(True)> Public Property Items() As Hashtable
        Get
            Return _items
        End Get
        Set(ByVal value As Hashtable)
            _items = value
        End Set
    End Property

    <Browsable(False)> Public Property Item(ByVal itemName As String) As Single
        Get
            If _items.ContainsKey(itemName) Then
                Return CSng(_items.Item(itemName))
            Else
                Return 0
            End If
        End Get
        Set(ByVal value As Single)
            If _items.ContainsKey(itemName) Then
                _items.Item(itemName) = value
            Else
                _items.Add(itemName, value)
            End If
        End Set
    End Property

    Public Function Validate(ByVal value As String) As String
        If _items.ContainsKey(value) Then Return value
        Return "none"

    End Function
End Class


Public Interface IIndicatorEntry
    Property ptrIndicator() As IIindciator
    Function displayText() As String

    '// optional campaigneritemtreenode
    'Property CITreenode() As CampaignerItemTreeNode

End Interface


'// these are the ones that are actually in the chit
'// they use the PTR item to 
<Serializable()> Public Class ValueIndicatorEntry : Implements IIndicatorEntry

    Private _ptrIndicator As ValueIndicator
    Private _currentValue As Single = 0
    '<NonSerialized()> Private _citn As CampaignerItemTreeNode

    Public Function DisplayText() As String Implements IIndicatorEntry.displayText
        If _ptrIndicator Is Nothing Then Return "0"
        Return _ptrIndicator.IndicatorName & ": " & _currentValue
    End Function

    Public Property ptrIndicator() As IIindciator Implements IIndicatorEntry.ptrIndicator
        Get
            Return _ptrIndicator
        End Get
        Set(ByVal value As IIindciator)
            _ptrIndicator = value
            '// reset the default value right neeeooww
            _currentValue = _ptrIndicator.defValue
        End Set
    End Property

    Public Property Value() As Single
        Get
            Return _currentValue
        End Get
        Set(ByVal value As Single)
            If _ptrIndicator Is Nothing Then
                _currentValue = 0
                Exit Property
            End If

            _currentValue = _ptrIndicator.Validate(value)

            'If _citn Is Nothing Then buildCITN()
            '_citn.Text = DisplayText()
        End Set
    End Property

    'Public Property CITreenode() As CampaignerItemTreeNode Implements IIndicatorEntry.CITreenode
    '    Get
    '        If _citn Is Nothing Then buildCITN()
    '        Return _citn
    '    End Get
    '    Set(ByVal value As CampaignerItemTreeNode)
    '        _citn = value
    '    End Set
    'End Property

    'Private Sub buildCITN()
    '    If _citn Is Nothing Then _citn = New CampaignerItemTreeNode
    '    _citn.ItemType = CampaignerItem_cgd.Indicator
    '    _citn.Item = Me
    '    _citn.Text = DisplayText()
    'End Sub
End Class

<Serializable()> Public Class NamedIndicatorEntry : Implements IIndicatorEntry

    Private _ptrindicator As NamedIndicator
    Private _name As String = "none"

    '<NonSerialized()> Private _citn As CampaignerItemTreeNode


    Public Function DisplayText() As String Implements IIndicatorEntry.displayText
        If _ptrindicator Is Nothing Then Return "none"
        Return _ptrindicator.IndicatorName & ": " & _name
    End Function

    Public Property ptrIndicator() As IIindciator Implements IIndicatorEntry.ptrIndicator
        Get
            Return _ptrindicator
        End Get
        Set(ByVal value As IIindciator)
            _ptrindicator = value
        End Set
    End Property

    Public Property name() As String
        Get
            Return _name
        End Get
        Set(ByVal value As String)
            _name = _ptrindicator.Validate(value)
            'If _citn Is Nothing Then buildCITN()
            '_citn.Text = DisplayText()

        End Set
    End Property

    'Public Property CITreenode() As CampaignerItemTreeNode Implements IIndicatorEntry.CITreenode
    '    Get
    '        Return _citn
    '    End Get
    '    Set(ByVal value As CampaignerItemTreeNode)
    '        If _citn Is Nothing Then buildCITN()

    '        _citn = value
    '    End Set
    'End Property

    'Private Sub buildCITN()
    '    If _citn Is Nothing Then _citn = New CampaignerItemTreeNode
    '    _citn.ItemType = CampaignerItem_cgd.Indicator
    '    _citn.Item = Me
    '    _citn.Text = DisplayText()
    'End Sub
End Class

<Serializable()> Public Class NamedValueIndicatorEntry : Implements IIndicatorEntry

    Private _ptrindicator As NamedValueIndicator
    Private _name As String = "none"
    '<NonSerialized()> Private _citn As CampaignerItemTreeNode

    Public Function DisplayText() As String Implements IIndicatorEntry.displayText
        If _ptrindicator Is Nothing Then Return "none [0]"
        Dim v As Single
        v = _ptrindicator.Item(_name)
        Return _ptrindicator.IndicatorName & " " & _name & " [" & v & "]"
    End Function

    Public Property ptrIndicator() As IIindciator Implements IIndicatorEntry.ptrIndicator
        Get
            Return _ptrindicator
        End Get
        Set(ByVal value As IIindciator)
            _ptrindicator = value
        End Set
    End Property

    Public Property Name() As String
        Get
            Return _name
        End Get
        Set(ByVal value As String)
            _name = _ptrindicator.Validate(value)
            'If _citn Is Nothing Then buildCITN()
            '_citn.Text = DisplayText()
        End Set
    End Property

    'Public Property CITreenode() As CampaignerItemTreeNode Implements IIndicatorEntry.CITreenode
    '    Get
    '        If _citn Is Nothing Then buildCITN()
    '        Return _citn
    '    End Get
    '    Set(ByVal value As CampaignerItemTreeNode)
    '        _citn = value
    '    End Set
    'End Property

    'Private Sub buildCITN()
    '    If _citn Is Nothing Then _citn = New CampaignerItemTreeNode

    '    _citn.ItemType = CampaignerItem_cgd.Indicator
    '    _citn.Item = Me
    '    _citn.Text = DisplayText()
    'End Sub

End Class

#End Region


<Serializable()> Public Class ObjectiveType
    Inherits GroundChitType
    Implements ICloneable

    Private mvarObjectiveRules As New Rules2
    Private mvarResources As New Resources
    Private mvarDetected As Boolean = False

    Public Sub ResetRuleCount(ByVal ruleTs As RuleTypes)
        ' resets the max rulecount and such 
        Dim RuleT As RuleType
        Dim rul As Rule

        Try
            ''''For Each key In mvarObjectiveRules.HT.Keys
            ''''    rul = mvarObjectiveRules.Item(key)
            ''''    ruleTKey = CampaignerGameData.CDGKEY_RULETYPE & rul.ruleTypeID
            ''''    RuleT = ruleTs.Item(ruleTKey)
            ''''    If RuleT.MaxUses > 0 Then rul.currentUses = 1 ' remember this was changed.
            ''''Next
            For Each rul In GCRules
                RuleT = rul.ptrRule 'ruleTs.Item(CampaignerGameData.CDGKEY_RULETYPE & rul.ruleTypeID)
                If RuleT.MaxUses > 0 Then rul.usesRemaining = 1
            Next
        Catch ex As Exception
            Throw ex
        End Try

    End Sub

    Public Sub GenerateResources()
        ' add resources to pool
        Dim Res As Resource
        Dim ResKey As String

        For Each ResKey In mvarResources.HT.Keys
            Res = mvarResources.Item(ResKey)
            If Res.AccrueAmount > 0 Then
                Res.CurrentAmount += Res.AccrueAmount
                If Res.CurrentAmount > Res.MaxAmount Then Res.CurrentAmount = Res.MaxAmount
            End If
        Next

    End Sub

    Public Overrides Function propertiestotreeview() As System.Windows.Forms.TreeNodeCollection
        Dim nodeCol As System.Windows.Forms.TreeNodeCollection

        nodeCol.Add("Type: " & MyBase.TypeName)
        nodeCol.Add("LOS: " & MyBase.LOS)
        nodeCol.Add("LOS Power: " & MyBase.LOSPower)
        nodeCol.Add("Size: " & MyBase.Size)
        nodeCol.Add("Uses ZOC: " & MyBase.UsesZOC.ToString)
        If MyBase.UsesZOC Then
            nodeCol.Add("ZOC: " & MyBase.ZOCRange)
        End If

        ' now put in rules and resources
        If mvarObjectiveRules.Count <> 0 Then
            Dim ruleCol As New System.Windows.Forms.TreeNode("Rules")
            'Dim rul As Rule
            'Dim key As String

            For Each rult As RuleType In mvarObjectiveRules
                ruleCol.Nodes.Add("junk")
                '   rul = mvarObjectiveRules.item(Key)
                'ruleCol.Nodes.Add(rul.ptrRule.RuleName)
                ruleCol.Nodes.Add(rult.RuleName)
            Next
            nodeCol.Add(ruleCol)
        End If

        If mvarResources.Count <> 0 Then

        End If

    End Function

    <Browsable(False)> Public Property Detected() As Boolean
        Get
            Return mvarDetected
        End Get
        Set(ByVal Value As Boolean)
            mvarDetected = Value
        End Set
    End Property

    <Browsable(False)> Public Property ObjectiveRules() As Rules2
        Get
            Return mvarObjectiveRules
        End Get
        Set(ByVal Value As Rules2)
            mvarObjectiveRules = Value
        End Set
    End Property

    <Browsable(False)> Public Property ObjectiveResources() As Resources
        Get
            Return mvarResources
        End Get
        Set(ByVal Value As Resources)
            mvarResources = Value
        End Set
    End Property

    <Browsable(False)> Public Overrides ReadOnly Property Key() As String
        Get
            Return cmplib01.CampaignerGameData.CGDKEY_OBJECTIVETYPE & MyBase.ID
        End Get
    End Property

    Public Function Clone() As Object Implements System.ICloneable.Clone
        Dim aClone As New cmplib01.ObjectiveType
        Dim ms As New MemoryStream(1000)
        Dim bf As New BinaryFormatter(Nothing, New StreamingContext(StreamingContextStates.Clone))

        ' serialize object into stream
        bf.Serialize(ms, Me)

        ' position stream pointer back to first byte
        ms.Seek(0, SeekOrigin.Begin)

        ' deserialize into the return object
        aClone = bf.Deserialize(ms)

        ' release memory
        ms.Close()

        Return aClone
    End Function
End Class


<Serializable()> Public Class ObjectiveTypes_col : Inherits CollectionBase
    Default Public Property item(ByVal index As Integer) As ObjectiveType
        Get
            Return InnerList.Item(index)
        End Get
        Set(ByVal value As ObjectiveType)
            InnerList.Item(index) = value
        End Set
    End Property

    Public Sub remove(ByVal obj As ObjectiveType)
        InnerList.Remove(obj)
    End Sub

    Public Sub add(ByVal value As ObjectiveType)
        InnerList.Add(value)
    End Sub

End Class


<Serializable()> Public Class UnitType
    Inherits GroundChitType
    Implements ICloneable

    '// "Flippable" parameters
    Private mvarMovementClassID As Int32
    Private mvarMovementSpeed As Single = 10
    Private _suggestedPointValue As Single = 0.0#
    Private _reinforcementRange As Single = 0.0#
    Private _movementRate As movementRate_mr = movementRate_mr.hour_mr
    ' mybase.zoc
    ' mybase.los
    ' mybase.size

    Private mvarOrder As String
    Private mvarWaypoints As New ArrayList(6) ' array of points
    Private mvarMoveRemaining As Int16 ' this is used only during the movementphase (and thus is the PIXEL count modified for this map)
    Private mvarStatus As GroundUnitStatus_cgd  ' only use this in legacy
    Private mvarTransportingOn As Int16 = -1 ' shows which unit this guy is embarked. -1 means none. (DEPRECATED)
    Private mvarROE As ROE_cgd = ROE_cgd.Halt
    Private mvarMoveOrder As MovementOrder_cgd = MovementOrder_cgd.Combat
    <NonSerialized()> Private _moveaccumulated As Single
    Private _costs As New ResourceCosts



    Public Function Clone() As Object Implements System.ICloneable.Clone
        Dim aClone As New cmplib01.UnitType
        Dim ms As New MemoryStream(1000)
        Dim bf As New BinaryFormatter(Nothing, New StreamingContext(StreamingContextStates.Clone))

        ' serialize object into stream
        bf.Serialize(ms, Me)

        ' position stream pointer back to first byte
        ms.Seek(0, SeekOrigin.Begin)

        ' deserialize into the return object
        aClone = bf.Deserialize(ms)

        ' release memory
        ms.Close()

        Return aClone
    End Function

    <Browsable(False)> Public Property Costs() As ResourceCosts
        Get
            Return _costs
        End Get
        Set(ByVal value As ResourceCosts)
            _costs = value
        End Set
    End Property

    <Category("Builder")> Public Property ReinforcementRange() As Single
        Get
            Return _reinforcementRange
        End Get
        Set(ByVal value As Single)
            _reinforcementRange = value
        End Set
    End Property

    <Category("Builder")> Public Property SuggestedPointValue() As Single
        Get
            Return _suggestedPointValue
        End Get
        Set(ByVal value As Single)
            _suggestedPointValue = value
        End Set
    End Property

    <Browsable(False)> Public Property MoveAccumulated() As Single
        Get
            Return _moveaccumulated
        End Get
        Set(ByVal value As Single)
            _moveaccumulated = value
        End Set
    End Property

    <Browsable(True), Category("Builder")> Public Property MovementRate() As movementRate_mr
        Get
            Return _movementRate
        End Get
        Set(ByVal value As movementRate_mr)
            _movementRate = value
        End Set
    End Property

    <Browsable(False)> Public Property MoveRemaining() As Int16
        Get
            Return mvarMoveRemaining
        End Get
        Set(ByVal Value As Int16)
            mvarMoveRemaining = Value
        End Set
    End Property

    <Browsable(False)> Public Property MovementClassID() As Int16
        Get
            Return mvarMovementClassID
        End Get
        Set(ByVal Value As Int16)
            mvarMovementClassID = Value
        End Set
    End Property

    <Category("Builder")> Public Property MovementSpeed() As Single
        Get
            Return mvarMovementSpeed
        End Get
        Set(ByVal Value As Single)
            mvarMovementSpeed = Value
        End Set
    End Property

    <Browsable(False)> Public Overrides Property BattleInvolvedInID() As Int16
        Get
            Return MyBase.BattleInvolvedInID
        End Get
        Set(ByVal Value As Int16)
            MyBase.BattleInvolvedInID = Value
            ' we clear all waypoints if we end up in battle.
            mvarWaypoints.Clear()
        End Set
    End Property

    <Browsable(False)> Public Property Order() As String
        Get
            Return mvarOrder
        End Get
        Set(ByVal Value As String)
            mvarOrder = Value
        End Set
    End Property

    <Browsable(False)> Public Property Waypoint(ByVal Index As Int32) As Point
        Get
            Try
                Return mvarWaypoints(Index)
            Catch
                Debug.WriteLine("Index out of bounds in UnitType.Waypoint")
            End Try
        End Get
        Set(ByVal Value As Point)
            Try
                mvarWaypoints(Index) = Value
            Catch
                Debug.WriteLine("Index out of bounds in UnitType.Waypoint")
            End Try
        End Set
    End Property

    <Browsable(False)> Public Property Waypoints() As ArrayList
        Get
            Return mvarWaypoints
        End Get
        Set(ByVal Value As ArrayList)
            mvarWaypoints = Value
        End Set
    End Property

    <Browsable(False)> Public Overrides ReadOnly Property Key() As String
        Get
            'Return cmplib01.CampaignerGameData.CDGKEY_UNITTYPE & MyBase.ID
            Return MyBase.Name
        End Get
    End Property

End Class


<Serializable()> Public Class UnitTypes_col : Inherits CollectionBase

    Default Public Property item(ByVal index As Integer) As UnitType
        Get
            Return InnerList.Item(index)
        End Get
        Set(ByVal value As UnitType)
            InnerList.Item(index) = value
        End Set
    End Property

    Public Sub remove(ByRef obj As UnitType)
        InnerList.Remove(obj)
    End Sub

    Public Sub add(ByRef value As UnitType)
        InnerList.Add(value)
    End Sub

End Class



<Serializable()> Public Class TokenType
    '// not flippable
    Private _tokenTypeName As String = "Token Type"
    Private _tokenRules As New Rules2
    Private _indicators As New Hashtable

    '// flippable
    Private _frontProperties As TokenFlippableProperties
    Private _flippedProperties As TokenFlippableProperties

    Public Overrides Function tostring() As String
        Return _tokenTypeName
    End Function

    Public Property Indicators() As Hashtable
        Get
            Return _indicators
        End Get
        Set(ByVal value As Hashtable)
            _indicators = value
        End Set
    End Property

    Public Property tokenTypeName() As String
        Get
            Return _tokenTypeName
        End Get
        Set(ByVal value As String)
            _tokenTypeName = value
        End Set
    End Property

    Public Property TokenRules() As Rules2
        Get
            Return _tokenRules
        End Get
        Set(ByVal value As Rules2)
            _tokenRules = value
        End Set
    End Property

    Public Property FrontProperties() As TokenFlippableProperties
        Get
            Return _frontProperties
        End Get
        Set(ByVal value As TokenFlippableProperties)
            _frontProperties = value
        End Set
    End Property

    Public Property FlippedProperties() As TokenFlippableProperties
        Get
            Return _flippedProperties
        End Get
        Set(ByVal value As TokenFlippableProperties)
            _flippedProperties = value
        End Set
    End Property
End Class


<Serializable()> Public Structure TokenFlippableProperties
    Public LOSRange As Single
    Public Size As Int16
    Public LOSPower As Single
    Public MovementSpeed As Single
    Public MovementClassID As Integer
    Public PointValue As Single
    Public ZOC As Single
    Public ReinforcementRange As Single
    Public TransportCapacity As Integer
    Public TransportCost As Integer
    Public CanBeTransported As Boolean
    Public CanTransport As Boolean
    Public icon As Bitmap

    Public Sub New(ByVal _losrange As Single, ByVal _size As Single, ByVal _lospower As Single, ByVal _movementspeed As Single, ByVal _moveclass As Integer, ByVal _pointvalue As Single, ByVal _zoc As Single, ByVal _reinforcementRange As Single, ByVal _transcost As Integer, ByVal _transcap As Integer)
        LOSRange = _losrange
        Size = _size
        LOSPower = _lospower
        MovementSpeed = _movementspeed
        MovementClassID = _moveclass
        PointValue = _pointvalue
        ZOC = _zoc
        ReinforcementRange = _reinforcementRange
        TransportCapacity = _transcap
        TransportCost = _transcost
    End Sub

    Public Sub New(ByVal _losrange As Single, ByVal _size As Single, ByVal _lospower As Single, ByVal _movementspeed As Single, ByVal _moveclass As Integer, ByVal _pointvalue As Single, ByVal _zoc As Single, ByVal _reinforcementRange As Single, ByVal _transcost As Integer, ByVal _transcap As Integer, ByVal _icon As Bitmap)
        LOSRange = _losrange
        Size = _size
        LOSPower = _lospower
        MovementSpeed = _movementspeed
        MovementClassID = _moveclass
        PointValue = _pointvalue
        ZOC = _zoc
        ReinforcementRange = _reinforcementRange
        TransportCapacity = _transcap
        TransportCost = _transcost
        icon = _icon
    End Sub

End Structure



<Serializable()> Public Class GroundChits
    Inherits System.Collections.CollectionBase
    Implements ICloneable

    Public Function Clone() As Object Implements System.ICloneable.Clone
        Dim aClone As New cmplib01.GroundChits
        Dim ms As New MemoryStream(1000)
        Dim bf As New BinaryFormatter(Nothing, New StreamingContext(StreamingContextStates.Clone))

        ' serialize object into stream
        bf.Serialize(ms, Me)

        ' position stream pointer back to first byte
        ms.Seek(0, SeekOrigin.Begin)

        ' deserialize into the return object
        aClone = bf.Deserialize(ms)

        ' release memory
        ms.Close()

        Return aClone
    End Function

    Public Sub Add(ByVal value As GroundChitType)
        InnerList.Add(value)
    End Sub

    Default Property item(ByVal index As Integer) As GroundChitType
        Get
            Return InnerList.Item(index)
        End Get
        Set(ByVal Value As GroundChitType)
            InnerList(index) = Value
        End Set
    End Property

    Public Sub Remove(ByRef value As GroundChitType)
        InnerList.Remove(value)
    End Sub

End Class

<Serializable()> Public Class Units
    Inherits System.Collections.CollectionBase
    Implements ICloneable

    Public Event ItemAdded(ByVal value As UnitType)
    Public Event ItemRemoved(ByVal obj As UnitType)


    Public Function Clone() As Object Implements System.ICloneable.Clone
        Dim aClone As New cmplib01.UnitType
        Dim ms As New MemoryStream(1000)
        Dim bf As New BinaryFormatter(Nothing, New StreamingContext(StreamingContextStates.Clone))

        ' serialize object into stream
        bf.Serialize(ms, Me)

        ' position stream pointer back to first byte
        ms.Seek(0, SeekOrigin.Begin)

        ' deserialize into the return object
        aClone = bf.Deserialize(ms)

        ' release memory
        ms.Close()

        Return aClone
    End Function

    Public Sub Add(ByVal value As UnitType)
        InnerList.Add(value)
        RaiseEvent ItemAdded(value)
    End Sub

    Default Property item(ByVal index As Integer) As UnitType
        Get
            Return CType(InnerList(index), UnitType)
        End Get
        Set(ByVal Value As UnitType)
            InnerList(index) = Value
        End Set
    End Property

    Public Sub Remove(ByRef value As UnitType)
        InnerList.Remove(value)
        RaiseEvent ItemRemoved(value)
    End Sub
End Class

<Serializable()> Public Class SmartWaypoint
    '// this allows improved waypoint actions.
    Private _loc As Point
    Private _speed As Single = 1 '// speeeeeeeeeeeeeed.
    Private _ordertext As String    '// dunno. Something for latah.

    Public Property LOC() As Point
        Get
            Return _loc
        End Get
        Set(ByVal value As Point)
            _loc = value
        End Set
    End Property

    Public Property Speed() As Single
        Get
            Return _speed
        End Get
        Set(ByVal value As Single)
            _speed = value
        End Set
    End Property

    Public Property OrderText() As String
        Get
            Return _ordertext
        End Get
        Set(ByVal value As String)
            _ordertext = value
        End Set
    End Property

End Class

<Serializable()> Public Class SmartWaypoints
    Inherits CollectionBase

    Default Public Property item(ByVal index As Integer) As SmartWaypoint
        Get
            Return InnerList.Item(index)
        End Get
        Set(ByVal value As SmartWaypoint)
            InnerList.Item(index) = value
        End Set
    End Property

    Public Sub add(ByVal value As SmartWaypoint)
        InnerList.Add(value)
    End Sub

    Public Sub remove(ByVal obj As SmartWaypoint)
        InnerList.Remove(obj)
    End Sub

End Class

#End Region

#Region "Elements"

<Serializable()> Public Class ElementManager
    ' handles the element types and element classes
    Private m_Classes As New ElementClasses
    Private m_ElementTypes As New ElementTypes
    Private m_ElementOptions As New ElementOptionTypes

    Public Function Import(ByVal filename As String) As Integer
        ' opens an existing campaigner game and imports its elements

    End Function

    Public Function Import(ByVal CGD As CampaignerGameData) As Integer
        ' or... pass in a game

    End Function

    Public Sub Export(ByVal filename As String)
        ' saves this manager's element types and element classes to the file.

    End Sub

    Public Property DefinedElementClasses() As ElementClasses
        Get
            Return m_Classes
        End Get
        Set(ByVal Value As ElementClasses)
            m_Classes = Value
        End Set
    End Property

    Public Property DefinedElementTypes() As ElementTypes
        Get
            Return m_ElementTypes
        End Get
        Set(ByVal Value As ElementTypes)
            m_ElementTypes = Value
        End Set
    End Property

    Public Property DefinedElementOptions() As ElementOptionTypes
        Get
            Return m_ElementOptions
        End Get
        Set(ByVal Value As ElementOptionTypes)
            m_ElementOptions = Value
        End Set
    End Property

End Class


<Serializable()> Public Class ElementClass
    Implements ICloneable

    ' these are used to organize elements into usable armies and other categorical breakdowns
    ' ie, space wolves, imperial guard, combine, etc
    Shared mCID As Integer
    Private m_ID As Integer
    Private m_ElementClassName As String
    Private m_ElementClassDescription As String
    Private m_Properties As String   ' for scalability

    Public Function Clone() As Object Implements System.ICloneable.Clone
        Dim aClone As New cmplib01.ElementClass
        Dim ms As New MemoryStream(1000)
        Dim bf As New BinaryFormatter(Nothing, New StreamingContext(StreamingContextStates.Clone))

        ' serialize object into stream
        bf.Serialize(ms, Me)

        ' position stream pointer back to first byte
        ms.Seek(0, SeekOrigin.Begin)

        ' deserialize into the return object
        aClone = bf.Deserialize(ms)

        ' release memory
        ms.Close()

        Return aClone
    End Function

    Public Overrides Function tostring() As String
        Return m_ElementClassName
    End Function

    Public Property ElementClassName() As String
        Get
            Return m_ElementClassName
        End Get
        Set(ByVal Value As String)
            m_ElementClassName = Value
        End Set
    End Property

    Public Property ElementClassDescription() As String
        Get
            Return m_ElementClassDescription
        End Get
        Set(ByVal Value As String)
            m_ElementClassDescription = Value
        End Set
    End Property

End Class

<Serializable()> Public Class ElementClasses
    ' a collection of ElementClasses specifically for the base element manager
    Inherits System.Collections.CollectionBase
    Implements ICloneable

    Public Function Clone() As Object Implements System.ICloneable.Clone
        Dim aClone As New cmplib01.ElementClasses
        Dim ms As New MemoryStream(1000)
        Dim bf As New BinaryFormatter(Nothing, New StreamingContext(StreamingContextStates.Clone))

        ' serialize object into stream
        bf.Serialize(ms, Me)

        ' position stream pointer back to first byte
        ms.Seek(0, SeekOrigin.Begin)

        ' deserialize into the return object
        aClone = bf.Deserialize(ms)

        ' release memory
        ms.Close()

        Return aClone
    End Function

    Public Sub Add(ByVal value As ElementClass)
        InnerList.Add(value)
    End Sub

    Default Property item(ByVal index As Integer) As ElementClass
        Get
            Return CType(InnerList(index), ElementClass)
        End Get
        Set(ByVal Value As ElementClass)
            InnerList.Item(index) = Value
        End Set
    End Property

    Public Sub Remove(ByRef value As ElementClass)
        ' cycle through all objects and find this guy, then... KILLLLLLLL >:D
        InnerList.Remove(value)
    End Sub

End Class


<Serializable()> Public Class ElementType
    Implements ICloneable

    ' this is the basic element template... such as Imperial Guard, Leman Russ, MKIII Ogre, etc.
    Shared mCID As Integer
    Private m_ID As Integer
    Private m_ElementClassName As String
    Private m_ElementPointValue As Integer   ' hidden for now
    Private m_ElementTypeName As String
    Private m_ElementMoveSpeed As Integer
    Private m_ElementMoveClassID As Integer
    Private m_ElementDescription As String
    Private m_Properties As String  ' for expansion into BUILDING units from Elements as opposed to simply adding them

    Public Function Clone() As Object Implements System.ICloneable.Clone
        Dim aClone As New cmplib01.ElementType
        Dim ms As New MemoryStream(1000)
        Dim bf As New BinaryFormatter(Nothing, New StreamingContext(StreamingContextStates.Clone))

        ' serialize object into stream
        bf.Serialize(ms, Me)

        ' position stream pointer back to first byte
        ms.Seek(0, SeekOrigin.Begin)

        ' deserialize into the return object
        aClone = bf.Deserialize(ms)

        ' release memory
        ms.Close()

        Return aClone
    End Function

    Public Overrides Function ToString() As String
        Return m_ElementTypeName
    End Function

    Public Property ElementClassName() As String
        Get
            Return m_ElementClassName
        End Get
        Set(ByVal Value As String)
            m_ElementClassName = Value
        End Set
    End Property

    Public Property ElementDescription() As String
        Get
            Return m_ElementDescription
        End Get
        Set(ByVal Value As String)
            m_ElementDescription = Value
        End Set
    End Property

    Public Property ElementTypeName() As String
        Get
            Return m_ElementTypeName
        End Get
        Set(ByVal Value As String)
            m_ElementTypeName = Value
        End Set
    End Property

    'these properties are hidden right now.
    Public Property ElementMoveSpeed() As Integer
        Get
            Return m_ElementMoveSpeed
        End Get
        Set(ByVal Value As Integer)
            m_ElementMoveSpeed = Value
        End Set
    End Property

    Public Property ElementPointValue() As Integer
        Get
            Return m_ElementPointValue
        End Get
        Set(ByVal Value As Integer)
            m_ElementPointValue = Value
        End Set
    End Property

    Public Property ElementMoveClassID() As Integer
        Get
            Return m_ElementMoveClassID
        End Get
        Set(ByVal Value As Integer)
            m_ElementMoveClassID = Value
        End Set
    End Property


End Class

<Serializable()> Public Class ElementTypes
    ' collection of Element Type objects... saved in the Campaigner Game Data
    Inherits System.Collections.CollectionBase
    Implements ICloneable


    Public Function Clone() As Object Implements System.ICloneable.Clone
        Dim aClone As New cmplib01.ElementTypes
        Dim ms As New MemoryStream(1000)
        Dim bf As New BinaryFormatter(Nothing, New StreamingContext(StreamingContextStates.Clone))

        ' serialize object into stream
        bf.Serialize(ms, Me)

        ' position stream pointer back to first byte
        ms.Seek(0, SeekOrigin.Begin)

        ' deserialize into the return object
        aClone = bf.Deserialize(ms)

        ' release memory
        ms.Close()

        Return aClone
    End Function

    Default Property Item(ByVal index As Integer) As ElementType
        Get
            Return CType(InnerList.Item(index), ElementType)
        End Get
        Set(ByVal Value As ElementType)
            InnerList.Item(index) = Value
        End Set
    End Property

    Sub Add(ByVal value As ElementType)
        InnerList.Add(value)
    End Sub

    Public Sub Remove(ByRef value As ElementType)
        InnerList.Remove(value)
    End Sub

End Class

<Serializable()> Public MustInherit Class Element
    ' this is added to a chit's 'ChitElements' property
    'Implements ICloneable

    Shared mCID As Int32
    Private m_ID As Int32
    Private m_ElementTypeName As String
    Private m_ElementName As String
    Private m_Properties As String
    Private m_Count As Integer
    Private m_Description As String
    Private m_ElementBaseCost As Integer 'cost per element
    ' here are some properties that may or may not be used... dunno. I guess it depends on how complicated we get.
    Private m_ElementOptions As New ElementOptions   ' these are little additions and such, like MeltaGun, Heavy weapons, etc.


    'Public Function Clone() As Object Implements System.ICloneable.Clone
    '    Dim aClone As New cmplib01.Element
    '    Dim ms As New MemoryStream(1000)
    '    Dim bf As New BinaryFormatter(Nothing, New StreamingContext(StreamingContextStates.Clone))

    '    ' serialize object into stream
    '    bf.Serialize(ms, Me)

    '    ' position stream pointer back to first byte
    '    ms.Seek(0, SeekOrigin.Begin)

    '    ' deserialize into the return object
    '    aClone = bf.Deserialize(ms)

    '    ' release memory
    '    ms.Close()

    '    Return aClone
    'End Function

    Public Function TotalCost() As Integer
        Dim tC As Integer
        tC = m_ElementBaseCost * m_Count
        Dim opto As ElementOption

        For Each opto In m_ElementOptions
            tC += ((opto.ElementOptionPointCost) * m_Count)
        Next
        Return tC

    End Function

    Public Property ElementName() As String
        Get
            Return m_ElementName
        End Get
        Set(ByVal Value As String)
            m_ElementName = Value
        End Set
    End Property

    Public Property ElementBaseCost() As Integer
        Get
            Return m_ElementBaseCost
        End Get
        Set(ByVal Value As Integer)
            m_ElementBaseCost = Value
        End Set
    End Property

    Public Property ElementTypeName() As String
        Get
            Return m_ElementTypeName
        End Get
        Set(ByVal Value As String)
            m_ElementTypeName = Value
        End Set
    End Property

    Public Property Count() As Integer
        Get
            Return m_Count
        End Get
        Set(ByVal Value As Integer)
            m_Count = Value
        End Set
    End Property

    Public Property Description() As String
        Get
            Return m_Description
        End Get
        Set(ByVal Value As String)
            m_Description = Value
        End Set
    End Property

    Public Property Options() As ElementOptions
        Get
            Return m_ElementOptions
        End Get
        Set(ByVal Value As ElementOptions)
            m_ElementOptions = Value
        End Set
    End Property

End Class

<Serializable()> Public Class Elements
    ' a list of existing Elements that can be added to a ground chit. Simple. Oh yeah BABY!. Oh yeah, this list will
    ' be persitent in XML. ( I guess I have to figure out how to do XML in .NET)
    ' this collection inherintly supports FOR NEXT loops. Nice. :P
    Inherits System.Collections.CollectionBase
    Implements ICloneable


    Public Overridable Function Clone() As Object Implements System.ICloneable.Clone
        'Dim aClone As New cmplib01.Elements
        'Dim ms As New MemoryStream(1000)
        'Dim bf As New BinaryFormatter(Nothing, New StreamingContext(StreamingContextStates.Clone))

        '' serialize object into stream
        'bf.Serialize(ms, Me)

        '' position stream pointer back to first byte
        'ms.Seek(0, SeekOrigin.Begin)

        '' deserialize into the return object
        'aClone = bf.Deserialize(ms)

        '' release memory
        'ms.Close()
        MessageBox.Show("Fuckall")
        'Return aClone
    End Function

    Default Overridable Property Item(ByVal index As Integer) As Element
        Get
            Return CType(InnerList.Item(index), Element)
        End Get
        Set(ByVal Value As Element)
            InnerList.Item(index) = Value
        End Set
    End Property

    Overridable Sub Add(ByVal value As Element)
        InnerList.Add(value)
    End Sub

    Public Overridable Sub Remove(ByRef value As Element)
        InnerList.Remove(value)
    End Sub

End Class

' there will probably be some restriction stuff in here, like armies... and stuff. Like armybuilder does. Whatever.
' I think I'll actually DESIGN this part before I write it. Good idea micah... gooooooood. 

<Serializable()> Public Class GroupableElement
    Inherits Element

    Private m_GroupName As String
    Private m_UsesGroupPV As Boolean

    Public Sub New()

    End Sub

    Public Sub New(ByVal fromType As ElementType, Optional ByVal count As Integer = 1)
        With Me
            .Count = count
            .Description = fromType.ElementDescription
            .ElementBaseCost = fromType.ElementPointValue
            .ElementName = fromType.ElementTypeName
            .ElementTypeName = fromType.ElementTypeName
        End With
    End Sub



#Region "Properties"
    Public Property GroupName() As String
        Get
            Return m_GroupName
        End Get
        Set(ByVal Value As String)
            m_GroupName = Value
        End Set
    End Property

    Public Property UsesGroupPV() As Boolean
        Get
            Return m_UsesGroupPV
        End Get
        Set(ByVal Value As Boolean)
            m_UsesGroupPV = Value
        End Set
    End Property

#End Region

End Class

<Serializable()> Public Class GroupableElements
    Inherits Elements
    ' A collection of elements that are groupable, also included is the Groups.

    Private m_Groups As New ElementGroups

    Public Shadows Function Clone() As GroupableElements
        Dim aClone As New cmplib01.Elements
        Dim ms As New MemoryStream(1000)
        Dim bf As New BinaryFormatter(Nothing, New StreamingContext(StreamingContextStates.Clone))

        ' serialize object into stream
        bf.Serialize(ms, Me)

        ' position stream pointer back to first byte
        ms.Seek(0, SeekOrigin.Begin)

        ' deserialize into the return object
        aClone = bf.Deserialize(ms)

        ' release memory
        ms.Close()

        Return aClone
    End Function

    Public Function ConvertToGroupable(ByVal Eles As Elements) As GroupableElements
        '// converts the provided object to a groupableelements class.
        'TODO: a real conversion? Maybe? Probably not. Since No one's used it yet, it makes little sense.
        Dim slagathor As New GroupableElements

        Dim ele As Element

        For Each ele In Eles
            If TypeOf ele Is GroupableElement Then
                slagathor.Add(ele)
            Else
                Dim newgroupable As New GroupableElement
                With newgroupable
                    .Count = ele.Count
                    .Description = ele.Description
                    .ElementBaseCost = ele.ElementBaseCost
                    .ElementName = ele.ElementName
                    .ElementTypeName = ele.ElementTypeName
                    .GroupName = "<Ungrouped>"
                    .Options = ele.Options
                    .UsesGroupPV = False
                End With
                slagathor.Add(newgroupable)
            End If

        Next

        Return slagathor

    End Function

    Public Property Groups() As ElementGroups
        Get
            Return m_Groups
        End Get
        Set(ByVal Value As ElementGroups)
            m_Groups = Value
        End Set
    End Property

    Public Overloads Sub Add(ByRef GroupEle As GroupableElement)
        InnerList.Add(GroupEle)
    End Sub

    Public Overloads Sub Remove(ByRef GroupEle As GroupableElement)
        InnerList.Remove(GroupEle)
    End Sub

End Class

<Serializable()> Public Class ElementGroup
    '// this is a group identifier. Individual elements can be placed in this group

    Private m_GroupName As String
    Private m_UseGroupPV As Boolean
    Private m_GroupPV As Integer
    Private m_ExtendedProperties As New GenericProperties


    Public Overrides Function ToString() As String
        Return m_GroupName
    End Function

#Region "Properties"
    Public Property GroupName() As String
        Get
            Return m_GroupName
        End Get
        Set(ByVal Value As String)
            m_GroupName = Value
        End Set
    End Property

    Public Property UseGroupPV() As Boolean
        Get
            Return m_UseGroupPV
        End Get
        Set(ByVal Value As Boolean)
            m_UseGroupPV = Value
        End Set
    End Property

    Public Property GroupPV() As Integer
        Get
            Return m_GroupPV
        End Get
        Set(ByVal Value As Integer)
            m_GroupPV = Value
        End Set
    End Property

    <Browsable(False)> Public Property ExtendedProperties() As GenericProperties
        Get
            Return m_ExtendedProperties
        End Get
        Set(ByVal Value As GenericProperties)
            m_ExtendedProperties = Value
        End Set
    End Property

#End Region

End Class

<Serializable()> Public Class ElementGroups
    Inherits Collections.CollectionBase

    Default Public Property Item(ByVal index As Integer) As ElementGroup
        Get
            Return InnerList.Item(index)
        End Get
        Set(ByVal Value As ElementGroup)
            InnerList.Item(index) = Value
        End Set
    End Property

    Public Sub Add(ByRef value As ElementGroup)
        InnerList.Add(value)
    End Sub

    Public Sub Remove(ByRef value As ElementGroup)
        InnerList.Remove(value)
    End Sub


End Class


<Serializable()> Public Class ElementOptionType
    Implements ICloneable

    Private m_ElementOptionTypeID As Integer
    Private m_ElementOptionTypeName As String
    Private m_ElementClassName As String   ' for filtering
    Private m_ElementPointCost As Integer   ' adds to the cost of the element applied to


    Public Function Clone() As Object Implements System.ICloneable.Clone
        Dim aClone As New cmplib01.ElementOptionType
        Dim ms As New MemoryStream(1000)
        Dim bf As New BinaryFormatter(Nothing, New StreamingContext(StreamingContextStates.Clone))

        ' serialize object into stream
        bf.Serialize(ms, Me)

        ' position stream pointer back to first byte
        ms.Seek(0, SeekOrigin.Begin)

        ' deserialize into the return object
        aClone = bf.Deserialize(ms)

        ' release memory
        ms.Close()

        Return aClone
    End Function

    Public Overrides Function ToString() As String
        Return m_ElementOptionTypeName
    End Function

    Public Property ElementOptionTypeID() As Integer
        Get
            Return m_ElementOptionTypeID
        End Get
        Set(ByVal Value As Integer)
            m_ElementOptionTypeID = Value
        End Set
    End Property

    Public Property ElementOptionTypeName() As String
        Get
            Return m_ElementOptionTypeName
        End Get
        Set(ByVal Value As String)
            m_ElementOptionTypeName = Value
        End Set
    End Property

    Public Property ElementClassName() As String
        Get
            Return m_ElementClassName
        End Get
        Set(ByVal Value As String)
            m_ElementClassName = Value
        End Set
    End Property

    Public Property ElementPointCost() As Integer
        Get
            Return m_ElementPointCost
        End Get
        Set(ByVal Value As Integer)
            m_ElementPointCost = Value
        End Set
    End Property

End Class

<Serializable()> Public Class ElementOptionTypes
    ' things like special options and whatever. Here for extending the base in the future
    Inherits System.Collections.CollectionBase
    Implements ICloneable


    Public Function Clone() As Object Implements System.ICloneable.Clone
        Dim aClone As New cmplib01.ElementOptionTypes
        Dim ms As New MemoryStream(1000)
        Dim bf As New BinaryFormatter(Nothing, New StreamingContext(StreamingContextStates.Clone))

        ' serialize object into stream
        bf.Serialize(ms, Me)

        ' position stream pointer back to first byte
        ms.Seek(0, SeekOrigin.Begin)

        ' deserialize into the return object
        aClone = bf.Deserialize(ms)

        ' release memory
        ms.Close()

        Return aClone
    End Function

    Public Sub Add(ByVal value As ElementOptionType)
        InnerList.Add(value)
    End Sub

    Default Property Item(ByVal index As Integer) As ElementOptionType
        Get
            Return CType(InnerList.Item(index), ElementOptionType)
        End Get
        Set(ByVal Value As ElementOptionType)
            InnerList.Item(index) = Value
        End Set
    End Property

    Public Sub remove(ByVal value As ElementOptionType)
        InnerList.Remove(value)
    End Sub

End Class


<Serializable()> Public Class ElementOption
    ' this is an instance of the an option type
    Implements ICloneable

    Private m_ElementOptionTypeName As String
    Private m_ElementOptionClassName As String
    Private m_ElementOptionPointCost As Integer
    Private m_ElementOptionCount As Integer = 1 ' we default to one. Yeah baby!

    Public Function Clone() As Object Implements System.ICloneable.Clone
        Dim aClone As New cmplib01.ElementOption
        Dim ms As New MemoryStream(1000)
        Dim bf As New BinaryFormatter(Nothing, New StreamingContext(StreamingContextStates.Clone))

        ' serialize object into stream
        bf.Serialize(ms, Me)

        ' position stream pointer back to first byte
        ms.Seek(0, SeekOrigin.Begin)

        ' deserialize into the return object
        aClone = bf.Deserialize(ms)

        ' release memory
        ms.Close()

        Return aClone
    End Function


    Public Overrides Function ToString() As String
        Return m_ElementOptionTypeName
    End Function

    Public Property ElementOptionTypeName() As String
        Get
            Return m_ElementOptionTypeName
        End Get
        Set(ByVal Value As String)
            m_ElementOptionTypeName = Value
        End Set
    End Property

    Public Property ElementOptionClassName() As String
        Get
            Return m_ElementOptionClassName
        End Get
        Set(ByVal Value As String)
            m_ElementOptionClassName = Value
        End Set
    End Property

    Public Property ElementOptionPointCost() As Integer
        Get
            Return m_ElementOptionPointCost
        End Get
        Set(ByVal Value As Integer)
            m_ElementOptionPointCost = Value
        End Set
    End Property

    Public Property ElementOptionCount() As Integer
        Get
            Return m_ElementOptionCount
        End Get
        Set(ByVal Value As Integer)
            m_ElementOptionCount = Value
        End Set
    End Property

End Class

<Serializable()> Public Class ElementOptions
    ' this collection is for an Element
    Inherits System.Collections.CollectionBase
    Implements ICloneable


    Public Function Clone() As Object Implements System.ICloneable.Clone
        Dim aClone As New cmplib01.ElementOptions
        Dim ms As New MemoryStream(1000)
        Dim bf As New BinaryFormatter(Nothing, New StreamingContext(StreamingContextStates.Clone))

        ' serialize object into stream
        bf.Serialize(ms, Me)

        ' position stream pointer back to first byte
        ms.Seek(0, SeekOrigin.Begin)

        ' deserialize into the return object
        aClone = bf.Deserialize(ms)

        ' release memory
        ms.Close()

        Return aClone
    End Function

    Default Public Property item(ByVal index As Integer) As ElementOption
        Get
            Return CType(InnerList.Item(index), ElementOption)
        End Get
        Set(ByVal Value As ElementOption)
            InnerList.Item(index) = Value
        End Set
    End Property

    Public Sub Add(ByVal Value As ElementOption)
        InnerList.Add(Value)
    End Sub

    Public Sub remove(ByVal Value As ElementOption)
        InnerList.Remove(Value)
    End Sub

End Class

#End Region

#Region "Rules"

<Serializable()> Public Class AssignedRule
    Implements ICloneable

    'Private m_OwningChitType As GroundChitClass_cgd
    Private m_OwningChit As ChitMember
    Private m_BattleAssignedTo As Int32
    Private m_Ru As Rule
    Private m_DisplayName As String
    Private m_Count As Integer
    Private m_ID As Integer

    Private m_ruleText As String


    Public Function Clone() As Object Implements System.ICloneable.Clone
        Dim aClone As New cmplib01.AssignedRule
        Dim ms As New MemoryStream(1000)
        Dim bf As New BinaryFormatter(Nothing, New StreamingContext(StreamingContextStates.Clone))

        ' serialize object into stream
        bf.Serialize(ms, Me)

        ' position stream pointer back to first byte
        ms.Seek(0, SeekOrigin.Begin)

        ' deserialize into the return object
        aClone = bf.Deserialize(ms)

        ' release memory
        ms.Close()

        Return aClone
    End Function

    Public Overrides Function ToString() As String
        Return m_DisplayName
    End Function


    Public Property RuleText() As String
        Get
            Return m_ruleText
        End Get
        Set(ByVal Value As String)
            m_ruleText = Value
        End Set
    End Property

    Public Property Count() As Integer
        Get
            Return m_Count
        End Get
        Set(ByVal Value As Integer)
            m_Count = Value
        End Set
    End Property

    Public Property DisplayName() As String
        Get
            Return m_DisplayName
        End Get
        Set(ByVal Value As String)
            m_DisplayName = Value
        End Set
    End Property

    'Public Property OwningChitType() As GroundChitClass_cgd
    '    Get
    '        Return m_OwningChitType
    '    End Get
    '    Set(ByVal Value As GroundChitClass_cgd)
    '        m_OwningChitType = Value
    '    End Set
    'End Property

    Public Property OwningChit() As ChitMember
        Get
            Return m_OwningChit
        End Get
        Set(ByVal Value As ChitMember)
            m_OwningChit = Value
        End Set
    End Property

    Public Property BattleAssignedTo() As Int32
        Get
            Return m_BattleAssignedTo
        End Get
        Set(ByVal Value As Int32)
            Value = m_BattleAssignedTo
        End Set
    End Property

    Public Property Ru() As Rule
        Get
            Return m_Ru
        End Get
        Set(ByVal Value As Rule)
            m_Ru = Value
        End Set
    End Property

    Public Property ID() As Integer
        Get
            Return m_ID
        End Get
        Set(ByVal Value As Integer)
            m_ID = Value
        End Set
    End Property

    Public Sub New()

    End Sub
End Class

<Serializable()> Public Class RuleType
    Implements ICloneable

    Shared mCID As Int16
    Private mvarRuleTypeID As Int16
    Private mvarRuleName As String = "New Rule"
    Private mvarBasicRange As Single = 0
    Private mvarAppliesDuring As RuleApplies_cgd = RuleApplies_cgd.Combat
    Private mvarMaxUses As Int16 = 1
    Private mvarRuleText As String = "Enter a description"
    Private mvarCoreRule As CoreRules_cgd = CoreRules_cgd.None
    Private _cooldownMinutes As Long = 0 '// the duration required to wait before this rule can be used again <internal use only>
    Private _cooldownRemaining As Long = 0 '// the amount of cooldown time remaining on this rule. <internal use only>

    Public Function Clone() As Object Implements System.ICloneable.Clone
        Dim aClone As New cmplib01.RuleType
        Dim ms As New MemoryStream(1000)
        Dim bf As New BinaryFormatter(Nothing, New StreamingContext(StreamingContextStates.Clone))

        ' serialize object into stream
        bf.Serialize(ms, Me)

        ' position stream pointer back to first byte
        ms.Seek(0, SeekOrigin.Begin)

        ' deserialize into the return object
        aClone = bf.Deserialize(ms)

        ' release memory
        ms.Close()

        Return aClone
    End Function

    Public Sub New()
        mCID += 1
        mvarRuleTypeID = mCID
    End Sub

    Public Sub BoostMCID()
        ' used to boost up the member class id, and the member id
        mCID += 5
        mvarRuleTypeID += 5
    End Sub

    Public Overrides Function ToString() As String
        Return mvarRuleName
    End Function

#Region "Property Declarations"

    <Browsable(False)> Public Property CooldownMinutes() As Long
        Get
            Return _cooldownMinutes
        End Get
        Set(ByVal value As Long)
            _cooldownMinutes = value
        End Set
    End Property

    <Browsable(False)> Public Property CooldownRemaining() As Long
        Get
            Return _cooldownRemaining
        End Get
        Set(ByVal value As Long)
            _cooldownRemaining = value
        End Set
    End Property

    <Browsable(False)> Public Property RuleTypeID() As Int16
        Get
            Return mvarRuleTypeID
        End Get
        Set(ByVal Value As Int16)
            mvarRuleTypeID = Value
        End Set
    End Property

    <Browsable(False)> Public ReadOnly Property Key() As String
        Get
            Return cmplib01.CampaignerGameData.CDGKEY_RULETYPE & mvarRuleTypeID
        End Get
    End Property

    Public Property RuleName() As String
        Get
            Return mvarRuleName
        End Get
        Set(ByVal Value As String)
            mvarRuleName = Value
        End Set
    End Property

    Public Property BasicRange() As Single
        Get
            Return mvarBasicRange
        End Get
        Set(ByVal Value As Single)
            mvarBasicRange = Value
        End Set
    End Property

    Public Property AppliesDuring() As RuleApplies_cgd
        Get
            Return mvarAppliesDuring
        End Get
        Set(ByVal Value As RuleApplies_cgd)
            mvarAppliesDuring = Value
        End Set
    End Property

    <Browsable(False)> Public Property MaxUses() As Int16
        Get
            Return mvarMaxUses
        End Get
        Set(ByVal Value As Int16)
            'mvarMaxUses = Value
            mvarMaxUses = 1   ' this is in here for clarity. There is a maximum and minimum of 1.
        End Set
    End Property

    Public Property RuleText() As String
        Get
            Return mvarRuleText
        End Get
        Set(ByVal Value As String)
            mvarRuleText = Value
        End Set
    End Property

    <Browsable(False)> Public Property CoreRule() As CoreRules_cgd
        Get
            Return mvarCoreRule
        End Get
        Set(ByVal Value As CoreRules_cgd)
            mvarCoreRule = Value
        End Set
    End Property

#End Region

End Class

<Serializable()> Public Class ResourceConsumingRuleType
    Inherits RuleType

    Private m_Costs As New ResourceCosts

    <Browsable(False)> Public Property Costs() As ResourceCosts
        Get
            Return m_Costs
        End Get
        Set(ByVal Value As ResourceCosts)
            m_Costs = Value
        End Set
    End Property

End Class

<Serializable()> Public Class RuleTypes
    Implements ICloneable

    Private mcol As New Hashtable

    Public Function Clone() As Object Implements System.ICloneable.Clone
        Dim aClone As New cmplib01.RuleTypes
        Dim ms As New MemoryStream(1000)
        Dim bf As New BinaryFormatter(Nothing, New StreamingContext(StreamingContextStates.Clone))

        ' serialize object into stream
        bf.Serialize(ms, Me)

        ' position stream pointer back to first byte
        ms.Seek(0, SeekOrigin.Begin)

        ' deserialize into the return object
        aClone = bf.Deserialize(ms)

        ' release memory
        ms.Close()

        Return aClone
    End Function

    Public Function Item(ByVal sKey As String) As RuleType
        Try
            Return mcol(sKey)
        Catch
            Debug.WriteLine("Could not find item '" & sKey & "' in RuleTypes Collection.")
        End Try
    End Function

    Public Sub Add(ByVal Item As RuleType, ByVal sKey As String)
        mcol.Add(sKey, Item)
    End Sub

    Public ReadOnly Property Count() As Int16
        Get
            Return mcol.Count
        End Get
    End Property

    Public ReadOnly Property HT() As Hashtable
        Get
            Return mcol
        End Get
    End Property

End Class

<Serializable()> Public Class Rule
    Implements ICloneable
    ' this is a particular instance of a rule for an objective or token, to be stuffed into the owning object's Rules property
    Private _ptrrule As RuleType
    Private _usesRemaining As Int16
    Private _battleAssignedTo As Battle 'Int16 = -1 ' default to none
    Private _active As Boolean = True
    Private _forceDeactive As Boolean = False '// this means CAMPAIGNER deactivated this rule. The owning faction must spend its resources to turn it on.

    Public Property forceDeactive() As Boolean
        Get
            Return _forceDeactive
        End Get
        Set(ByVal value As Boolean)
            _forceDeactive = value
        End Set
    End Property

    Public Property Active() As Boolean
        Get
            Return _active
        End Get
        Set(ByVal value As Boolean)
            _active = value
        End Set
    End Property

    Public Property battleAssignedTo() As Battle
        Get
            Return _battleAssignedTo
        End Get
        Set(ByVal value As Battle)
            _battleAssignedTo = value
        End Set
    End Property

    Public Property ptrRule() As RuleType
        Get
            Return _ptrrule
        End Get
        Set(ByVal value As RuleType)
            _ptrrule = value
        End Set
    End Property

    Public Property usesRemaining() As Int16
        Get
            Return _usesRemaining
        End Get
        Set(ByVal value As Int16)
            _usesRemaining = value
        End Set
    End Property

    Public Function Clone() As Object Implements System.ICloneable.Clone
        Dim aClone As New cmplib01.Rule
        Dim ms As New MemoryStream(1000)
        Dim bf As New BinaryFormatter(Nothing, New StreamingContext(StreamingContextStates.Clone))

        ' serialize object into stream
        bf.Serialize(ms, Me)

        ' position stream pointer back to first byte
        ms.Seek(0, SeekOrigin.Begin)

        ' deserialize into the return object
        aClone = bf.Deserialize(ms)

        ' release memory
        ms.Close()

        Return aClone
    End Function

    Public Sub New()

    End Sub

    Public Overrides Function ToString() As String
        Return ptrRule.RuleName
    End Function

End Class

'<Serializable()> Public Class Rules
'    Implements ICloneable

'    Private mcol As New Hashtable(20)

'    Public Function Clone() As Object Implements System.ICloneable.Clone
'        Dim aClone As New cmplib01.Rules
'        Dim ms As New MemoryStream(1000)
'        Dim bf As New BinaryFormatter(Nothing, New StreamingContext(StreamingContextStates.Clone))

'        ' serialize object into stream
'        bf.Serialize(ms, Me)

'        ' position stream pointer back to first byte
'        ms.Seek(0, SeekOrigin.Begin)

'        ' deserialize into the return object
'        aClone = bf.Deserialize(ms)

'        ' release memory
'        ms.Close()

'        Return aClone
'    End Function

'    Public Function Item(ByVal sKey As String) As Rule
'        Try
'            Return mcol(sKey)
'        Catch
'            Debug.WriteLine("Could not find item '" & sKey & "' in Rules Collection.")
'        End Try
'    End Function

'    Public Sub Add(ByVal Item As Rule, ByVal sKey As String)
'        mcol.Add(sKey, Item)
'    End Sub

'    Public ReadOnly Property Count() As Int16
'        Get
'            Return mcol.Count
'        End Get
'    End Property

'    Public ReadOnly Property HT() As Hashtable
'        Get
'            Return mcol
'        End Get
'    End Property

'End Class

<Serializable()> Public Class Rules2
    Inherits System.Collections.CollectionBase
    Implements ICloneable

    Public Function Clone() As Object Implements System.ICloneable.Clone
        Dim aClone As New cmplib01.Rules2
        Dim ms As New MemoryStream(1000)
        Dim bf As New BinaryFormatter(Nothing, New StreamingContext(StreamingContextStates.Clone))

        ' serialize object into stream
        bf.Serialize(ms, Me)

        ' position stream pointer back to first byte
        ms.Seek(0, SeekOrigin.Begin)

        ' deserialize into the return object
        aClone = bf.Deserialize(ms)

        ' release memory
        ms.Close()

        Return aClone
    End Function

    Public Sub Add(ByVal value As RuleType)
        InnerList.Add(value)
    End Sub

    Default Property item(ByVal index As Integer) As RuleType
        Get
            Return CType(InnerList(index), RuleType)
        End Get
        Set(ByVal Value As RuleType)
            InnerList(index) = Value
        End Set
    End Property

    Public Sub Remove(ByRef value As RuleType)
        InnerList.Remove(value)
    End Sub

End Class


<Serializable()> Public Class ChitRules_c : Inherits CollectionBase


    Default Public Property item(ByVal index As Integer) As Rule
        Get
            Return InnerList.Item(index)
        End Get
        Set(ByVal value As Rule)
            InnerList.Item(index) = value
        End Set
    End Property

    Public Sub add(ByVal value As Rule)
        InnerList.Add(value)
    End Sub

    Public Sub remove(ByVal obj As Rule)
        InnerList.Remove(obj)
    End Sub

End Class

#End Region

#Region "Core Rules"

<Serializable()> Public MustInherit Class CoreRule
    Inherits Rule

    Public MustOverride ReadOnly Property CoreRuleName() As String

End Class

<Serializable()> Public Class AirInterceptCoreRule
    Inherits CoreRule

    Public Overrides ReadOnly Property CoreRuleName() As String
        Get
            Return "Intercept"
        End Get
    End Property
End Class

<Serializable()> Public Class BridgingCoreRule
    Inherits CoreRule

    Public Sub New(ByRef copyFrom As Rule)
        MyBase.usesRemaining = copyFrom.usesRemaining
        'MyBase.ruleID = copyFrom.ruleID
        'MyBase.ruleName = copyFrom.ruleName
        MyBase.ptrRule = copyFrom.ptrRule
        MyBase.battleAssignedTo = copyFrom.battleAssignedTo
    End Sub

    Public Overrides ReadOnly Property CoreRuleName() As String
        Get
            Return "Bridging"
        End Get
    End Property
End Class

<Serializable()> Public Class EngineeringCoreRule
    Inherits CoreRule

    Public Sub New(ByRef copyFrom As Rule)
        MyBase.usesRemaining = copyFrom.usesRemaining
        'MyBase.ruleID = copyFrom.ruleID
        'MyBase.ruleName = copyFrom.ruleName
        MyBase.ptrRule = copyFrom.ptrRule
        MyBase.battleAssignedTo = copyFrom.battleAssignedTo
    End Sub

    Public Overrides ReadOnly Property CoreRuleName() As String
        Get
            Return "Engineering"
        End Get
    End Property
End Class

<Serializable()> Public Class ProtectedAreaCoreRule
    Inherits CoreRule

    Public Sub New(ByRef copyFrom As Rule)
        MyBase.usesRemaining = copyFrom.usesRemaining
        'MyBase.ruleID = copyFrom.ruleID
        'MyBase.ruleName = copyFrom.ruleName
        MyBase.ptrRule = copyFrom.ptrRule
        MyBase.battleAssignedTo = copyFrom.battleAssignedTo
    End Sub

    Public Overrides ReadOnly Property CoreRuleName() As String
        Get
            Return "Protected"
        End Get
    End Property
End Class

<Serializable()> Public Class AirDropCoreRule
    Inherits CoreRule

    Public Sub New(ByRef copyFrom As Rule)
        MyBase.usesRemaining = copyFrom.usesRemaining
        'MyBase.ruleID = copyFrom.ruleID
        'MyBase.ruleName = copyFrom.ruleName
        MyBase.ptrRule = copyFrom.ptrRule
        MyBase.battleAssignedTo = copyFrom.battleAssignedTo
    End Sub

    Public Overrides ReadOnly Property CoreRuleName() As String
        Get
            Return "Air Drop"
        End Get
    End Property
End Class

<Serializable()> Public Class TransportCoreRule
    Inherits CoreRule

    Private m_TransportedUnits As New GroundChits

    Public Sub New(ByRef copyFrom As Rule)
        MyBase.usesRemaining = copyFrom.usesRemaining
        'MyBase.ruleID = copyFrom.ruleID
        'MyBase.ruleName = copyFrom.ruleName
        MyBase.ptrRule = copyFrom.ptrRule
        MyBase.battleAssignedTo = copyFrom.battleAssignedTo
    End Sub

    Public Overrides ReadOnly Property CoreRuleName() As String
        Get
            Return "Transport"
        End Get
    End Property

    Public Property TransportedUnits() As GroundChits
        Get
            Return m_TransportedUnits
        End Get
        Set(ByVal Value As GroundChits)
            m_TransportedUnits = Value
        End Set
    End Property

End Class

<Serializable()> Public Class TransportableCoreRule
    Inherits CoreRule

    Public Sub New(ByRef copyFrom As Rule)
        MyBase.usesRemaining = copyFrom.usesRemaining
        'MyBase.ruleID = copyFrom.ruleID
        'MyBase.ruleName = copyFrom.ruleName
        MyBase.ptrRule = copyFrom.ptrRule
        MyBase.battleAssignedTo = copyFrom.battleAssignedTo
    End Sub

    Public Overrides ReadOnly Property CoreRuleName() As String
        Get
            Return "Transportable"
        End Get
    End Property
End Class

<Serializable()> Public Class SpecialOperationsCoreRule
    Inherits CoreRule

    Public Sub New(ByRef copyFrom As Rule)
        MyBase.usesRemaining = copyFrom.usesRemaining
        'MyBase.ruleID = copyFrom.ruleID
        'MyBase.ruleName = copyFrom.ruleName
        MyBase.ptrRule = copyFrom.ptrRule
        MyBase.battleAssignedTo = copyFrom.battleAssignedTo
    End Sub

    Public Overrides ReadOnly Property CoreRuleName() As String
        Get
            Return "Special Operations"
        End Get
    End Property
End Class

<Serializable()> Public Class DeploymentCoreRule
    Inherits CoreRule

    Public Sub New(ByRef copyFrom As Rule)
        MyBase.usesRemaining = copyFrom.usesRemaining
        'MyBase.ruleID = copyFrom.ruleID
        'MyBase.ruleName = copyFrom.ruleName
        MyBase.ptrRule = copyFrom.ptrRule
        MyBase.battleAssignedTo = copyFrom.battleAssignedTo
    End Sub

    Public Overrides ReadOnly Property CoreRuleName() As String
        Get
            Return "Deployment"
        End Get
    End Property
End Class

<Serializable()> Public Class FieldCraftCoreRule
    Inherits CoreRule

    Public Sub New(ByRef copyFrom As Rule)
        MyBase.usesRemaining = copyFrom.usesRemaining
        'MyBase.ruleID = copyFrom.ruleID
        'MyBase.ruleName = copyFrom.ruleName
        MyBase.ptrRule = copyFrom.ptrRule
        MyBase.battleAssignedTo = copyFrom.battleAssignedTo
    End Sub

    Public Overrides ReadOnly Property CoreRuleName() As String
        Get
            Return "Fieldcraft"
        End Get
    End Property
End Class

<Serializable()> Public Class ScoutCoreRule
    Inherits CoreRule

    Public Sub New(ByRef copyFrom As Rule)
        MyBase.usesRemaining = copyFrom.usesRemaining
        'MyBase.ruleID = copyFrom.ruleID
        'MyBase.ruleName = copyFrom.ruleName
        MyBase.ptrRule = copyFrom.ptrRule
        MyBase.battleAssignedTo = copyFrom.battleAssignedTo
    End Sub

    Public Overrides ReadOnly Property CoreRuleName() As String
        Get
            Return "Scout"
        End Get
    End Property
End Class

<Serializable()> Public Class AirTransportable
    Inherits CoreRule

    Public Overrides ReadOnly Property CoreRuleName() As String
        Get
            Return "Air Transportable"
        End Get
    End Property
End Class

#End Region

#Region "Resources"
<Serializable()> Public Class ResourceType
    Implements ICloneable

    Shared mCID As Int16
    Private mvarResourceTypeID As Int16
    Private mvarResourceName As String
    Private mvarResourceDescription As String

    Public Function Clone() As Object Implements System.ICloneable.Clone
        Dim aClone As New cmplib01.ResourceTypes
        Dim ms As New MemoryStream(1000)
        Dim bf As New BinaryFormatter(Nothing, New StreamingContext(StreamingContextStates.Clone))

        ' serialize object into stream
        bf.Serialize(ms, Me)

        ' position stream pointer back to first byte
        ms.Seek(0, SeekOrigin.Begin)

        ' deserialize into the return object
        aClone = bf.Deserialize(ms)

        ' release memory
        ms.Close()

        Return aClone
    End Function

    Public Sub New()
        mCID += 1
        mvarResourceTypeID = mCID
    End Sub

    Public Sub BoostMCID()
        mCID += 5
        mvarResourceTypeID = mCID
    End Sub

    Public Overrides Function ToString() As String
        Return mvarResourceName
    End Function

    <Browsable(False)> Public Property ResourceTypeID() As Int16
        Get
            Return mvarResourceTypeID
        End Get
        Set(ByVal Value As Int16)
            mvarResourceTypeID = Value
        End Set
    End Property

    <Browsable(False)> Public ReadOnly Property Key() As String
        Get
            Return cmplib01.CampaignerGameData.CDGKEY_RESOURCETYPE & mvarResourceTypeID
        End Get
    End Property

    Public Property ResourceName() As String
        Get
            Return mvarResourceName
        End Get
        Set(ByVal Value As String)
            mvarResourceName = Value
        End Set
    End Property

    Public Property ResourceDescription() As String
        Get
            Return mvarResourceDescription
        End Get
        Set(ByVal Value As String)
            mvarResourceDescription = Value
        End Set
    End Property

End Class

<Serializable()> Public Class ResourceTypes
    Private mcol As New Hashtable(20)

    Public Function Item(ByVal sKey As String) As ResourceType
        Try
            Return mcol(sKey)
        Catch
            Debug.WriteLine("Could not find item '" & sKey & "' in ResourceTypes Collection.")
        End Try
    End Function

    Public Sub Add(ByVal Item As ResourceType, ByVal sKey As String)
        mcol.Add(sKey, Item)
    End Sub

    Public ReadOnly Property Count() As Int16
        Get
            Return mcol.Count
        End Get
    End Property

    Public ReadOnly Property HT() As Hashtable
        Get
            Return mcol
        End Get
    End Property

End Class

<Serializable()> Public Class Resource
    Shared mCID As Int16
    Private mvarResourceTypeID As Int16
    Private mvarMaxAmount As Int16
    Private mvarAccrues As Boolean
    Private mvarAccrueAmount As Int16
    Private mvarCurrentAmount As Int16
    Private mvarResourceName As String
    Private mvarResourceID As Int16

    Public Sub New()
        mCID += 1
        mvarResourceID = mCID
    End Sub

    Public Overrides Function ToString() As String
        Return mvarResourceName
    End Function

    Public ReadOnly Property Key() As String
        Get
            Return cmplib01.CampaignerGameData.CDGKEY_RESOURCE & mvarResourceID
        End Get
    End Property

    Public Property ResourceTypeID() As Int16
        Get
            Return mvarResourceTypeID
        End Get
        Set(ByVal Value As Int16)
            mvarResourceTypeID = Value
        End Set
    End Property

    Public Property MaxAmount() As Int16
        Get
            Return (mvarMaxAmount)
        End Get
        Set(ByVal Value As Int16)
            mvarMaxAmount = Value
        End Set
    End Property

    Public Property Accrues() As Boolean
        Get
            Return mvarAccrues
        End Get
        Set(ByVal Value As Boolean)
            mvarAccrues = Value
        End Set
    End Property

    Public Property AccrueAmount() As Int16
        Get
            Return (mvarAccrueAmount)
        End Get
        Set(ByVal Value As Int16)
            mvarAccrueAmount = Value
        End Set
    End Property

    Public Property CurrentAmount() As Int16
        Get
            Return mvarCurrentAmount
        End Get
        Set(ByVal Value As Int16)
            mvarCurrentAmount = Value
        End Set
    End Property

    Public Property ResourceName() As String
        Get
            Return mvarResourceName
        End Get
        Set(ByVal Value As String)
            mvarResourceName = Value
        End Set
    End Property

End Class

<Serializable()> Public Class Resources
    ' collection of resource objects, for use with objectives, to tally them up!
    Private mcol As New Hashtable

    Public Function Item(ByVal sKey As String) As Resource
        Try
            Return mcol(sKey)
        Catch
            Debug.WriteLine("Could not find item '" & sKey & "' in Resources Collection.")
        End Try
    End Function

    Public Sub Add(ByVal Item As Resource, ByVal sKey As String)
        mcol.Add(sKey, Item)
    End Sub

    Public ReadOnly Property Count() As Int16
        Get
            Return mcol.Count
        End Get
    End Property

    Public ReadOnly Property HT() As Hashtable
        Get
            Return mcol
        End Get
    End Property

End Class

<Serializable()> Public Class ResourceCost
    Private m_ResourceTypeID As Integer
    Private m_ResourceTypeName As String
    Private m_ResourceCost As Integer

    Public Overrides Function ToString() As String
        Return m_ResourceTypeName & " [" & m_ResourceCost & "]"
    End Function

    Public Property ResourceTypeID() As Integer
        Get
            Return m_ResourceTypeID
        End Get
        Set(ByVal Value As Integer)
            m_ResourceTypeID = Value
        End Set
    End Property

    Public Property ResourceTypeName() As String
        Get
            Return m_ResourceTypeName
        End Get
        Set(ByVal Value As String)
            m_ResourceTypeName = Value
        End Set
    End Property

    Public Property ResourceCost() As Integer
        Get
            Return m_ResourceCost
        End Get
        Set(ByVal Value As Integer)
            m_ResourceCost = Value
        End Set
    End Property

End Class

<Serializable()> Public Class ResourceCosts
    Inherits CollectionBase

    Default Public Property Item(ByVal index As Integer) As ResourceCost
        Get
            Return InnerList.Item(index)
        End Get
        Set(ByVal Value As ResourceCost)
            InnerList.Item(index) = Value
        End Set
    End Property

    Public Sub Add(ByRef Item As ResourceCost)
        InnerList.Add(Item)
    End Sub

    Public Sub Remove(ByRef item As ResourceCost)
        InnerList.Remove(item)
    End Sub

End Class

<Serializable()> Public Class DeploymentPointResource
    Inherits ResourceType

    Public Sub New()
        MyBase.ResourceName = "Deployment Point"
        MyBase.ResourceDescription = "Used when a 'Deployment' core rule is invoked. The deploying chit must have enough deployment points to cover the cost of the unit being deployed."
    End Sub

End Class

#End Region

#Region "Orders"
<Serializable()> Public Class OrderType
    Implements ICloneable

    Shared mCID As Int16
    Private mvarOrderID As Int16
    Private mvarOrderName As String
    Private mvarOrderFlag As Int16
    Private mvarDescription As String

    Public Function Clone() As Object Implements System.ICloneable.Clone
        Dim aClone As New cmplib01.OrderType
        Dim ms As New MemoryStream(1000)
        Dim bf As New BinaryFormatter(Nothing, New StreamingContext(StreamingContextStates.Clone))

        ' serialize object into stream
        bf.Serialize(ms, Me)

        ' position stream pointer back to first byte
        ms.Seek(0, SeekOrigin.Begin)

        ' deserialize into the return object
        aClone = bf.Deserialize(ms)

        ' release memory
        ms.Close()

        Return aClone
    End Function

    Public Sub New()
        mCID += 1
        mvarOrderID = mCID
        mvarOrderName = "New Order " & mvarOrderID
    End Sub

    Public Property Description() As String
        Get
            Return mvarDescription
        End Get
        Set(ByVal Value As String)
            mvarDescription = Value
        End Set
    End Property

    Public Property OrderFlag() As Int16
        Get
            Return mvarOrderFlag
        End Get
        Set(ByVal Value As Int16)
            mvarOrderFlag = Value
        End Set
    End Property

    Public Sub BoostMCID()
        ' used to boost up the member class id, and the member id
        mCID += 5
        mvarOrderID += 5
    End Sub

    Public Overrides Function ToString() As String
        Return mvarOrderName
    End Function

    Public ReadOnly Property OrderID() As Int16
        Get
            Return mvarOrderID
        End Get
    End Property

    Public ReadOnly Property Key() As String
        Get
            Return cmplib01.CampaignerGameData.CDGKEY_ORDER & mvarOrderID
        End Get
    End Property

    Public Property OrderName() As String
        Get
            Return mvarOrderName
        End Get
        Set(ByVal Value As String)
            mvarOrderName = Value
        End Set
    End Property

End Class

<Serializable()> Public Class OrderTypes
    Implements ICloneable

    Private mcol As New Hashtable

    Public Function Clone() As Object Implements System.ICloneable.Clone
        Dim aClone As New cmplib01.OrderTypes
        Dim ms As New MemoryStream(1000)
        Dim bf As New BinaryFormatter(Nothing, New StreamingContext(StreamingContextStates.Clone))

        ' serialize object into stream
        bf.Serialize(ms, Me)

        ' position stream pointer back to first byte
        ms.Seek(0, SeekOrigin.Begin)

        ' deserialize into the return object
        aClone = bf.Deserialize(ms)

        ' release memory
        ms.Close()

        Return aClone
    End Function

    Public Function Item(ByVal sKey As String) As OrderType
        Try
            Return mcol(sKey)
        Catch
            Debug.WriteLine("Could not find item '" & sKey & "' in OrderTypes Collection.")
        End Try
    End Function

    Public Sub Add(ByVal Item As OrderType, ByVal sKey As String)
        mcol.Add(sKey, Item)
    End Sub

    Public ReadOnly Property Count() As Int16
        Get
            Return mcol.Count
        End Get
    End Property

    Public ReadOnly Property HT() As Hashtable
        Get
            Return mcol
        End Get
    End Property
End Class

#End Region

#Region "Factions"
<Serializable()> Public Class Faction
    Implements ICloneable

    Shared mCID As Int16
    Private mvarFactionID As Int16
    Private mvarFactionName As String
    Private mvarFactionDescription As String
    Private mvarFactionFreePoints As Int32            ' remaining undeployed points.
    Private mvarFactionDeployedPoints As Int32        ' the amount of points deployed and alive, automatically calculated.
    Private mvarFactionTotalDeployedPoints As Int32   ' the total points that have been deployed, including units that are destroyed
    Private mvarFactionTotalPoints As Int32           ' the total point value given to a faction at the beginning of the game. This number is NOT reduced.
    Private mvarOrderOfBattle As New ChitMembers

    Private mcolChitDetection As New Hashtable(20)
    Private mvarExtendedProperties As New GenericProperties
    Private mvarVictoryConditions As New VictoryConditions

    Private _pvEndofTurn As New Hashtable

    Public Property pvEndofTurn() As Hashtable
        Get
            Return _pvEndofTurn
        End Get
        Set(ByVal value As Hashtable)
            _pvEndofTurn = value
        End Set
    End Property

    Public Function Clone() As Object Implements System.ICloneable.Clone
        Dim aClone As New cmplib01.Faction
        Dim ms As New MemoryStream(1000)
        Dim bf As New BinaryFormatter(Nothing, New StreamingContext(StreamingContextStates.Clone))

        ' serialize object into stream
        bf.Serialize(ms, Me)

        ' position stream pointer back to first byte
        ms.Seek(0, SeekOrigin.Begin)

        ' deserialize into the return object
        aClone = bf.Deserialize(ms)

        ' release memory
        ms.Close()
        If aClone.pvEndofTurn Is Nothing Then aClone.pvEndofTurn = New Hashtable

        Return aClone
    End Function

    Public Function Item(ByVal sKey As String) As ChitDetection
        Try
            Return mcolChitDetection(sKey)
        Catch
            Throw New NullReferenceException
        End Try
    End Function

    Public Sub Add(ByVal Item As ChitDetection, ByVal sKey As String)
        mcolChitDetection.Add(sKey, Item)
    End Sub

    Public ReadOnly Property Count() As Int16
        Get
            Return mcolChitDetection.Count
        End Get
    End Property

    'Public ReadOnly Property HTChitDetection() As Hashtable
    '    Get
    '        Return mcolChitDetection
    '    End Get
    'End Property

    Public Sub New()
        mCID += 1
        mvarFactionID = mCID
    End Sub

    Public Sub New(ByVal facName As String, ByVal Descrip As String, ByVal startingPoints As Int16, ByVal freePoints As Int16, ByVal deployedPoints As Int16)
        Me.New()
        mvarFactionName = facName
        mvarFactionDescription = Descrip
        mvarFactionTotalPoints = startingPoints
        mvarFactionFreePoints = freePoints
        mvarFactionDeployedPoints = deployedPoints
    End Sub

    Public Overrides Function ToString() As String
        Return mvarFactionName
    End Function

    Public Property OrderOfBattle() As ChitMembers
        Get
            Return mvarOrderOfBattle
        End Get
        Set(ByVal Value As ChitMembers)
            mvarOrderOfBattle = Value
        End Set
    End Property

    Public Property FactionID() As Int16
        Get
            Return mvarFactionID
        End Get
        Set(ByVal Value As Int16)
            mvarFactionID = Value
        End Set
    End Property

    Public Property FactionName() As String
        Get
            Return mvarFactionName
        End Get
        Set(ByVal Value As String)
            mvarFactionName = Value
        End Set
    End Property

    Public Property FactionDescription() As String
        Get
            Return mvarFactionDescription
        End Get
        Set(ByVal Value As String)
            mvarFactionDescription = Value
        End Set
    End Property

    Public ReadOnly Property FactionFreePoints() As Int32
        Get
            Return mvarFactionTotalPoints - mvarFactionDeployedPoints
        End Get
    End Property

    Public Property FactionDeployedPoints() As Int32
        Get
            Return mvarFactionDeployedPoints
        End Get
        Set(ByVal Value As Int32)
            mvarFactionDeployedPoints = Value
        End Set
    End Property

    Public Property FactionTotalDeployedPoints() As Int32
        Get
            Return mvarFactionTotalDeployedPoints
        End Get
        Set(ByVal Value As Int32)
            mvarFactionTotalDeployedPoints = Value
        End Set
    End Property

    Public Property FactionTotalPoints() As Int32
        Get
            Return mvarFactionTotalPoints
        End Get
        Set(ByVal Value As Int32)
            mvarFactionTotalPoints = Value
        End Set
    End Property

    Public ReadOnly Property Key() As String
        Get
            Return cmplib01.CampaignerGameData.CDGKEY_FACTION & mvarFactionID
        End Get
    End Property

    Public Property ExtendedProperties() As GenericProperties
        Get
            Return mvarExtendedProperties
        End Get
        Set(ByVal Value As GenericProperties)
            mvarExtendedProperties = Value
        End Set
    End Property

    Public Property FactionVictoryConditions() As VictoryConditions
        Get
            Return mvarVictoryConditions
        End Get
        Set(ByVal Value As VictoryConditions)
            mvarVictoryConditions = Value
        End Set
    End Property

End Class



<Serializable()> Public Class Factions
    Implements ICloneable

    Private mcol As New Hashtable(1)

    Public Function Clone() As Object Implements System.ICloneable.Clone
        Dim aClone As New cmplib01.Factions
        Dim ms As New MemoryStream(1000)
        Dim bf As New BinaryFormatter(Nothing, New StreamingContext(StreamingContextStates.Clone))

        ' serialize object into stream
        bf.Serialize(ms, Me)

        ' position stream pointer back to first byte
        ms.Seek(0, SeekOrigin.Begin)

        ' deserialize into the return object
        aClone = bf.Deserialize(ms)

        ' release memory
        ms.Close()

        Return aClone
    End Function

    Public Sub New()
        ' add the two basic factions
        Dim fac As New Faction("Blue Force", "Blue Force", 10000, 0, 0)
        mcol.Add(fac.Key, fac)

        Dim fac2 As New Faction("Red Force", "Red Force", 10000, 0, 0)
        mcol.Add(fac2.Key, fac2)

        '// additional test faction
        '        Dim fac3 As New Faction("Gray Force", "Gray Force", 10000, 0, 0)
        '        mcol.Add(fac3.Key, fac3)

    End Sub

    Public Function Item(ByVal sKey As String) As Faction
        Try
            Return mcol(sKey)
        Catch
            Debug.WriteLine("Could not find item '" & sKey & "' in Factions Collection.")
        End Try
    End Function

    Public Sub Add(ByVal Item As Faction, ByVal sKey As String)
        mcol.Add(sKey, Item)
    End Sub

    Public ReadOnly Property Count() As Int16
        Get
            Return mcol.Count
        End Get
    End Property

    Public ReadOnly Property HT() As Hashtable
        Get
            Return mcol
        End Get
    End Property

End Class

#End Region

#Region "Messages"
<Serializable()> Public Class Messagem
    Implements ICloneable

    Shared mCID As Int16
    Private mvarMessageID As Int16
    Private mvarSendingPlayerID As Int64
    Private mvarReceivingPlayerID As Int64
    Private mvarTitle As String
    Private mvarMessage As String
    Private mvarTurnActive As Int16
    Private mvarViewed As Boolean


    Public Function Clone() As Object Implements System.ICloneable.Clone
        Dim aClone As New cmplib01.Messagem
        Dim ms As New MemoryStream(1000)
        Dim bf As New BinaryFormatter(Nothing, New StreamingContext(StreamingContextStates.Clone))

        ' serialize object into stream
        bf.Serialize(ms, Me)

        ' position stream pointer back to first byte
        ms.Seek(0, SeekOrigin.Begin)

        ' deserialize into the return object
        aClone = bf.Deserialize(ms)

        ' release memory
        ms.Close()

        Return aClone
    End Function

    Public Sub New()
        mCID += 1
        mvarMessageID = mCID
    End Sub

    Public Sub BoostMCID()
        mCID += 5
        mvarMessageID = mCID
    End Sub

    Public Overrides Function ToString() As String
        Return mvarTitle & " [" & mvarTurnActive & "]"
    End Function

    Public Property MessageID() As Int16
        Get
            Return mvarMessageID
        End Get
        Set(ByVal Value As Int16)
            mvarMessageID = Value
        End Set
    End Property

    Public Property SendingPlayerID() As Int64
        Get
            Return mvarSendingPlayerID
        End Get
        Set(ByVal Value As Int64)
            mvarSendingPlayerID = Value
        End Set
    End Property

    Public Property ReceivingPlayerID() As Int64
        Get
            Return mvarReceivingPlayerID
        End Get
        Set(ByVal Value As Int64)
            mvarReceivingPlayerID = Value
        End Set
    End Property

    Public Property Title() As String
        Get
            Return mvarTitle
        End Get
        Set(ByVal Value As String)
            mvarTitle = Value
        End Set
    End Property

    Public Property Message() As String
        Get
            Return mvarMessage
        End Get
        Set(ByVal Value As String)
            mvarMessage = Value
        End Set
    End Property

    Public Property TurnActive() As Int16
        Get
            Return mvarTurnActive
        End Get
        Set(ByVal Value As Int16)
            mvarTurnActive = Value
        End Set
    End Property

    Public Property Viewed() As Boolean
        Get
            Return mvarViewed
        End Get
        Set(ByVal Value As Boolean)
            mvarViewed = Value
        End Set
    End Property
End Class

<Serializable()> Public Class Messages
    Implements ICloneable

    Private mcol As New Hashtable


    Public Function Clone() As Object Implements System.ICloneable.Clone
        Dim aClone As New cmplib01.Messages
        Dim ms As New MemoryStream(1000)
        Dim bf As New BinaryFormatter(Nothing, New StreamingContext(StreamingContextStates.Clone))

        ' serialize object into stream
        bf.Serialize(ms, Me)

        ' position stream pointer back to first byte
        ms.Seek(0, SeekOrigin.Begin)

        ' deserialize into the return object
        aClone = bf.Deserialize(ms)

        ' release memory
        ms.Close()

        Return aClone
    End Function

    Public Function Item(ByVal sKey As String) As Messagem
        Try
            Return mcol(sKey)
        Catch
            Debug.WriteLine("Could not find item '" & sKey & "' in Messages Collection.")
        End Try
    End Function

    Public Sub Add(ByVal Item As Messagem, ByVal sKey As String)
        mcol.Add(sKey, Item)
    End Sub

    Public ReadOnly Property Count() As Int16
        Get
            Return mcol.Count
        End Get
    End Property

    Public ReadOnly Property HT() As Hashtable
        Get
            Return mcol
        End Get
    End Property

End Class
#End Region

#Region "DeploymentZones"
<Serializable()> Public Class DeploymentZone
    Implements ICloneable

    Private mvarMapID As Int16
    Private mvarZoneID As Int16
    Private mvarZoneName As String
    Private mvarLocation As Point
    Private mvarActive As Boolean = False
    Private mvarFactionID As Int16 = -1
    Private mvarCapturable As Boolean = False
    Private mvarCaptureEvent As CaptureEvent_cgd = CaptureEvent_cgd.ChangeOwnership
    Private mvarCaptured As Boolean = False
    Private mvarMaxDeploymentPerTurn As Int32 = -1    ' no maximum
    Private mvarMaxTotalDeploy As Int32 = -1               ' no max
    Private mvarBoundaryZone As Boolean = False
    Private mvarPointsDeployedThisTurn As Int32
    <NonSerialized()> Private mvarBoundaryPath As System.Drawing.Drawing2D.PathData      ' of points no doubt to recreate the graphics path, if its a boundary zone
    Private boundaryPoints() As PointF ' the serializable form of pathdata
    Private mvarWidth As Int16 = 60                 ' if its not a boundary zone
    Private mvarHeight As Int16 = 60                ' if its not a boundary zone
    Private _unlimitedMax As Boolean = False
    Private _unlimitedPerTurn As Boolean = False

    Private _Trespassed As Boolean = False   '// marked to TRUE if an enemy passes through this deployment zone during the turn, once its set, it remains.
    Private _contested As Boolean = False '// if both factions have units here, it's contested.

    Public Function Clone() As Object Implements System.ICloneable.Clone
        Dim aClone As New cmplib01.DeploymentZone
        Dim ms As New MemoryStream(1000)
        Dim bf As New BinaryFormatter(Nothing, New StreamingContext(StreamingContextStates.Clone))

        ' serialize object into stream
        bf.Serialize(ms, Me)

        ' position stream pointer back to first byte
        ms.Seek(0, SeekOrigin.Begin)

        ' deserialize into the return object
        aClone = bf.Deserialize(ms)

        ' release memory
        ms.Close()

        Return aClone
    End Function

    Friend Sub SetBoundaryPathToPoints()
        ' converts the boundarypath to a point arraylist since pathdata cannot be serialized.
        boundaryPoints = mvarBoundaryPath.Points
    End Sub

    Friend Sub SetBoundaryPointsToPath()
        ' converts from the serialized arraylist of points to the non-serializable pathdata
        mvarBoundaryPath = New System.Drawing.Drawing2D.PathData
        mvarBoundaryPath.Points = boundaryPoints

    End Sub

    Public Overrides Function ToString() As String
        Return mvarZoneName
    End Function

    Public Property Trespassed() As Boolean
        Get
            Return _Trespassed
        End Get
        Set(ByVal value As Boolean)
            _Trespassed = value
        End Set
    End Property

    Public Property Contested() As Boolean
        Get
            Return _contested
        End Get
        Set(ByVal value As Boolean)
            _contested = value
        End Set
    End Property

    Public Property MapID() As Int16
        Get
            Return mvarMapID
        End Get
        Set(ByVal Value As Int16)
            mvarMapID = Value
        End Set
    End Property

    Public Property ZoneID() As Int16
        Get
            Return mvarZoneID
        End Get
        Set(ByVal Value As Int16)
            mvarZoneID = Value
        End Set
    End Property

    Public Property ZoneName() As String
        Get
            Return mvarZoneName
        End Get
        Set(ByVal Value As String)
            mvarZoneName = Value
        End Set
    End Property

    Public Property Location() As Point
        Get
            Return mvarLocation
        End Get
        Set(ByVal Value As Point)
            mvarLocation = Value
        End Set
    End Property

    Public Property Active() As Boolean
        Get
            Return mvarActive
        End Get
        Set(ByVal Value As Boolean)
            mvarActive = Value
        End Set
    End Property

    Public Property FactionID() As Int16
        Get
            Return mvarFactionID
        End Get
        Set(ByVal Value As Int16)
            mvarFactionID = Value
        End Set
    End Property

    Public Property Capturable() As Boolean
        Get
            Return mvarCapturable
        End Get
        Set(ByVal Value As Boolean)
            mvarCapturable = Value
        End Set
    End Property

    Public Property CaptureEvent() As CaptureEvent_cgd
        Get
            Return mvarCaptureEvent
        End Get
        Set(ByVal Value As CaptureEvent_cgd)
            mvarCaptureEvent = Value
        End Set
    End Property

    Public Property Captured() As Boolean
        Get
            Return mvarCaptured
        End Get
        Set(ByVal Value As Boolean)
            mvarCaptured = Value
        End Set
    End Property

    Public Property MaxDeploymentPerTurn() As Int32
        Get
            Return mvarMaxDeploymentPerTurn
        End Get
        Set(ByVal Value As Int32)
            mvarMaxDeploymentPerTurn = Value
        End Set
    End Property

    Public Property MaxTotalDeploy() As Int32
        Get
            Return mvarMaxTotalDeploy
        End Get
        Set(ByVal Value As Int32)
            mvarMaxTotalDeploy = Value
        End Set
    End Property

    Public Property Width() As Int16
        Get
            Return mvarWidth
        End Get
        Set(ByVal Value As Int16)
            mvarWidth = Value
        End Set
    End Property

    Public Property Height() As Int16
        Get
            Return mvarHeight
        End Get
        Set(ByVal Value As Int16)
            mvarHeight = Value
        End Set
    End Property

    Public Property BoundaryZone() As Boolean
        Get
            Return mvarBoundaryZone
        End Get
        Set(ByVal Value As Boolean)
            mvarBoundaryZone = Value
        End Set
    End Property

    Public Property BoundaryPath() As System.Drawing.Drawing2D.PathData
        Get
            Return mvarBoundaryPath
        End Get
        Set(ByVal Value As System.Drawing.Drawing2D.PathData)
            mvarBoundaryPath = Value
        End Set
    End Property

    Public ReadOnly Property BoundaryGraphicsPath() As System.Drawing.Drawing2D.GraphicsPath
        Get
            ' used to return a graphics path of this deployment zone
            Dim graphPath As New System.Drawing.Drawing2D.GraphicsPath
            Dim lastPnt As PointF
            Dim pnt As PointF
            Dim i As Int32

            If boundaryPoints.GetUpperBound(0) <= 1 Then
                Return Nothing
            End If

            For i = 1 To boundaryPoints.GetUpperBound(0) - 1
                lastPnt = boundaryPoints(i - 1)
                pnt = boundaryPoints(i)
                graphPath.AddLine(lastPnt, pnt)
            Next

            Return graphPath
        End Get
    End Property

    Public Property PointsDeployedThisTurn() As Int32
        Get
            Return mvarPointsDeployedThisTurn
        End Get
        Set(ByVal Value As Int32)
            mvarPointsDeployedThisTurn = Value
        End Set
    End Property

End Class

<Serializable()> Public Class DeploymentZones
    Implements ICloneable

    Private mcol As New Hashtable

    Public Function Clone() As Object Implements System.ICloneable.Clone
        Dim aClone As New cmplib01.DeploymentZones
        Dim ms As New MemoryStream(1000)
        Dim bf As New BinaryFormatter(Nothing, New StreamingContext(StreamingContextStates.Clone))

        ' serialize object into stream
        bf.Serialize(ms, Me)

        ' position stream pointer back to first byte
        ms.Seek(0, SeekOrigin.Begin)

        ' deserialize into the return object
        aClone = bf.Deserialize(ms)

        ' release memory
        ms.Close()

        Return aClone
    End Function

    Friend Sub SetPathToPoints()
        Dim dep As DeploymentZone
        Dim key As String

        For Each key In mcol.Keys
            dep = mcol.Item(key)
            dep.SetBoundaryPathToPoints()
        Next
    End Sub

    Friend Sub SetPointsToPath()
        Dim dep As DeploymentZone
        Dim key As String

        For Each key In mcol.Keys
            dep = mcol.Item(key)
            dep.SetBoundaryPointsToPath()
        Next
    End Sub

    Public Function Item(ByVal sKey As String) As DeploymentZone
        Try
            Return mcol(sKey)
        Catch
            Debug.WriteLine("Could not find item '" & sKey & "' in DeploymentZones Collection.")
        End Try
    End Function

    Public Sub Add(ByVal Item As DeploymentZone, ByVal sKey As String)
        mcol.Add(sKey, Item)
    End Sub

    Public ReadOnly Property HT() As Hashtable
        Get
            Return mcol
        End Get
    End Property

End Class
#End Region

#Region "Battles"
<Serializable()> Public Class Battle
    Implements ICloneable

    Shared mCID As Int16
    Private mvarBattleID As Int16
    Private mvarAttackingChitInitiative As Int16
    Private mvarDefendingChitInitiative As Int16
    Private mvarAttackingFactionID As Int16
    Private mvarDefendingFactionID As Int16
    Private mvarBattleResult As BattleResult_cgd
    Private mvarBattleName As String
    Private mvarBattleLocation As Point
    Private mvarInvolvedChits As New ChitMembers
    Private mvarAttackerAssignedRules As ChitRules_c ' The object type is ASSIGNEDRULE
    Private mvarDefenderAssignedRules As ChitRules_c ' same here.
    ' This is so players can submit their combat actions seperately.
    Private mvarAttackerReady As Boolean
    Private mvarDefenderReady As Boolean
    Private mvarPhaseActive As Integer

    Public Function Clone() As Object Implements System.ICloneable.Clone
        Dim aClone As New cmplib01.Battle
        Dim ms As New MemoryStream(1000)
        Dim bf As New BinaryFormatter(Nothing, New StreamingContext(StreamingContextStates.Clone))

        ' serialize object into stream
        bf.Serialize(ms, Me)

        ' position stream pointer back to first byte
        ms.Seek(0, SeekOrigin.Begin)

        ' deserialize into the return object
        aClone = bf.Deserialize(ms)

        ' release memory
        ms.Close()

        Return aClone
    End Function

    Public Sub New()
        mCID += 1
        mvarBattleID = mCID
        mvarAttackerAssignedRules = New ChitRules_c
        mvarDefenderAssignedRules = New ChitRules_c
    End Sub

    Public Overrides Function ToString() As String
        Return "Battle " & mvarBattleName
    End Function

    Public Property PhaseActive() As Integer
        Get
            Return mvarPhaseActive
        End Get
        Set(ByVal Value As Integer)
            mvarPhaseActive = Value
        End Set
    End Property

    Public Property AttackerReady() As Boolean
        Get
            Return mvarAttackerReady
        End Get
        Set(ByVal Value As Boolean)
            mvarAttackerReady = Value
        End Set
    End Property

    Public Property DefenderReady() As Boolean
        Get
            Return mvarDefenderReady
        End Get
        Set(ByVal Value As Boolean)
            mvarDefenderReady = Value
        End Set
    End Property

    Public Property AttackingFactionID() As Int16
        Get
            Return mvarAttackingFactionID
        End Get
        Set(ByVal Value As Int16)
            mvarAttackingFactionID = Value
        End Set
    End Property

    Public Property DefendingFactionID() As Int16
        Get
            Return mvarDefendingFactionID
        End Get
        Set(ByVal Value As Int16)
            mvarDefendingFactionID = Value
        End Set
    End Property

    Public Property AttackerAssignedRules() As ChitRules_c
        Get
            Return mvarAttackerAssignedRules
        End Get
        Set(ByVal Value As ChitRules_c)
            mvarAttackerAssignedRules = Value
        End Set
    End Property

    Public Property DefenderAssignedRules() As ChitRules_c
        Get
            Return mvarDefenderAssignedRules
        End Get
        Set(ByVal Value As ChitRules_c)
            mvarDefenderAssignedRules = Value
        End Set
    End Property

    Public Property InvolvedChits() As ChitMembers
        Get
            Return mvarInvolvedChits
        End Get
        Set(ByVal Value As ChitMembers)
            mvarInvolvedChits = Value
        End Set
    End Property

    Public ReadOnly Property Key() As String
        Get
            Return CampaignerGameData.CDGKEY_BATTLE & mvarBattleID
        End Get
    End Property

    Public Property BattleLocation() As Point
        Get
            Return mvarBattleLocation
        End Get
        Set(ByVal Value As Point)
            mvarBattleLocation = Value
        End Set
    End Property

    Public Property BattleName() As String
        Get
            Return mvarBattleName
        End Get
        Set(ByVal Value As String)
            mvarBattleName = Value
        End Set
    End Property

    Public Property BattleID() As Int64
        Get
            Return mvarBattleID
        End Get
        Set(ByVal Value As Int64)
            mvarBattleID = Value
        End Set
    End Property

    Public Property AttackingChitInitiative() As Int16
        Get
            Return mvarAttackingChitInitiative
        End Get
        Set(ByVal Value As Int16)
            mvarAttackingChitInitiative = Value
        End Set
    End Property

    Public Property DefendingChitInitiative() As Int16
        Get
            Return mvarDefendingChitInitiative
        End Get
        Set(ByVal Value As Int16)
            mvarDefendingChitInitiative = Value
        End Set
    End Property

    Public Property BattleResult() As BattleResult_cgd
        Get
            Return mvarBattleResult
        End Get
        Set(ByVal Value As BattleResult_cgd)
            mvarBattleResult = Value
        End Set
    End Property

    Public ReadOnly Property BattleResultString() As String
        Get
            Select Case mvarBattleResult
                Case BattleResult_cgd.AttackerMarginalVictory : Return "Attacker Marginal Victory"
                Case BattleResult_cgd.AttackerVictory : Return "Attacker Victory"
                Case BattleResult_cgd.DefenderMarginalVictory : Return "Defender Marginal Victory"
                Case BattleResult_cgd.DefenderVictory : Return "Defender Victory"
                Case BattleResult_cgd.Draw : Return "Draw"
                Case BattleResult_cgd.NotFinished : Return "Not Finished"
            End Select
        End Get

    End Property

End Class

<Serializable()> Public Class Battle_2
    Inherits Battle

    'Private m_AttackerAssigned As New ChitRules_c
    'Private m_DefenderAssigned As New ChitRules_c


    Public Property AttackerAssigned() As ChitRules_c
        Get
            Return MyBase.AttackerAssignedRules
        End Get
        Set(ByVal Value As ChitRules_c)
            MyBase.AttackerAssignedRules = Value

        End Set
    End Property

    Public Property DefenderAssigned() As ChitRules_c
        Get
            Return MyBase.DefenderAssignedRules
        End Get
        Set(ByVal Value As ChitRules_c)
            MyBase.DefenderAssignedRules = Value
        End Set
    End Property

End Class

<Serializable()> Public Class Battles
    Implements ICloneable

    Private mcol As New Hashtable


    Public Function Clone() As Object Implements System.ICloneable.Clone
        Dim aClone As New cmplib01.Battles
        Dim ms As New MemoryStream(1000)
        Dim bf As New BinaryFormatter(Nothing, New StreamingContext(StreamingContextStates.Clone))

        ' serialize object into stream
        bf.Serialize(ms, Me)

        ' position stream pointer back to first byte
        ms.Seek(0, SeekOrigin.Begin)

        ' deserialize into the return object
        aClone = bf.Deserialize(ms)

        ' release memory
        ms.Close()

        Return aClone
    End Function

    Public Function Item(ByVal sKey As String) As Battle
        Try
            Return mcol(sKey)
        Catch
            Debug.WriteLine("Could not find item '" & sKey & "' in Battles Collection.")
        End Try
    End Function

    Public Sub Add(ByVal Item As Battle, ByVal sKey As String)
        mcol.Add(sKey, Item)
    End Sub

    Public ReadOnly Property HT() As Hashtable
        Get
            Return mcol
        End Get
    End Property

End Class
#End Region

#Region "Diplomacy"
<Serializable()> Public Class Diplomacy
    Implements ICloneable

    ' each faction should be represented, but for now, everyone HATES everyone!!! hahahahahahaha

    Public Function Clone() As Object Implements System.ICloneable.Clone
        Dim aClone As New cmplib01.Diplomacy
        Dim ms As New MemoryStream(1000)
        Dim bf As New BinaryFormatter(Nothing, New StreamingContext(StreamingContextStates.Clone))

        ' serialize object into stream
        bf.Serialize(ms, Me)

        ' position stream pointer back to first byte
        ms.Seek(0, SeekOrigin.Begin)

        ' deserialize into the return object
        aClone = bf.Deserialize(ms)

        ' release memory
        ms.Close()

        Return aClone
    End Function

    Public Property DiplomaticStanding(ByVal Faction1 As Int16, ByVal Faction2 As Int16) As DiplomaticStanding_cgd
        Get
            Return DiplomaticStanding_cgd.Enemy
        End Get
        Set(ByVal Value As DiplomaticStanding_cgd)

        End Set
    End Property
End Class
#End Region

#Region "Map Labels"
<Serializable()> Public Class MapLabel
    Implements ICloneable

    Private mvarMapLabelID As Int16
    Public LabelText As String
    Public LabelColor As Color = Color.WhiteSmoke
    Public Location As Point
    Public MapID As Int16
    Public Visible As Boolean = True


    Public Function Clone() As Object Implements System.ICloneable.Clone
        Dim aClone As New cmplib01.MapLabel
        Dim ms As New MemoryStream(1000)
        Dim bf As New BinaryFormatter(Nothing, New StreamingContext(StreamingContextStates.Clone))

        ' serialize object into stream
        bf.Serialize(ms, Me)

        ' position stream pointer back to first byte
        ms.Seek(0, SeekOrigin.Begin)

        ' deserialize into the return object
        aClone = bf.Deserialize(ms)

        ' release memory
        ms.Close()

        Return aClone
    End Function

    Public Overrides Function ToString() As String
        Return LabelText
    End Function

    Public Property MapLabelID() As Int16
        Get
            Return mvarMapLabelID
        End Get
        Set(ByVal Value As Int16)
            mvarMapLabelID = Value
        End Set
    End Property

End Class

<Serializable()> Public Class MapLabels
    Implements ICloneable

    Private mcol As New Hashtable


    Public Function Clone() As Object Implements System.ICloneable.Clone
        Dim aClone As New cmplib01.MapLabels
        Dim ms As New MemoryStream(1000)
        Dim bf As New BinaryFormatter(Nothing, New StreamingContext(StreamingContextStates.Clone))

        ' serialize object into stream
        bf.Serialize(ms, Me)

        ' position stream pointer back to first byte
        ms.Seek(0, SeekOrigin.Begin)

        ' deserialize into the return object
        aClone = bf.Deserialize(ms)

        ' release memory
        ms.Close()

        Return aClone
    End Function

    Public Function Item(ByVal sKey As String) As MapLabel
        Try
            Return mcol(sKey)
        Catch
            Debug.WriteLine("Could not find item '" & sKey & "' in MapLabels Collection.")
        End Try
    End Function

    Public Sub Add(ByVal Item As MapLabel, ByVal sKey As String)
        mcol.Add(sKey, Item)
    End Sub

    Public ReadOnly Property HT() As Hashtable
        Get
            Return mcol
        End Get
    End Property

End Class
#End Region

#Region "Player"
<Serializable()> Public Class Player
    Implements ICloneable

    Shared mCID As Int64
    Private m_PlayerID As Integer
    Private m_PlayerName As String
    Private m_Password As String
    Private m_FactionKey As String
    Private m_TurnComplete As Boolean
    Private m_UseElementsForPointValue As Boolean
    Private m_ExtendedProperties As String
    Private m_IsInCombat As Boolean = False
    Private m_ignoreEndGame As Boolean
    Private m_ignoreRepositionMessage As Boolean = False

    '// here for the stupid solo xxP
    Private m_NOPLAY As Boolean = False

    'Public Property param1() As String
    '    Get
    '        If m_ExtendedProperties.Length = 0 Then
    '            '// create the extended properties
    '            mCIDD()
    '        End If
    '        Return rP1()

    '    End Get
    '    Set(ByVal value As String)
    '        sP1(value)
    '    End Set
    'End Property

    'Public Property param2() As String
    '    Get
    '        If m_ExtendedProperties.Length = 0 Then mCIDD()
    '        Return rP2()
    '    End Get
    '    Set(ByVal value As String)
    '        sP2(value)
    '    End Set
    'End Property

    Public Property NoPlay() As Boolean
        Get
            Return m_NOPLAY
        End Get
        Set(ByVal value As Boolean)
            m_NOPLAY = value
        End Set
    End Property

    Public Property EProperties() As String
        Get
            Return m_ExtendedProperties
        End Get
        Set(ByVal value As String)
            m_ExtendedProperties = value
        End Set
    End Property

    Public Property IgnoreRepositionMessage() As Boolean
        Get
            Return m_ignoreRepositionMessage
        End Get
        Set(ByVal value As Boolean)
            m_ignoreRepositionMessage = value
        End Set
    End Property

    Public Property IgnoreEndGame() As Boolean
        Get
            Return m_ignoreEndGame
        End Get
        Set(ByVal value As Boolean)
            m_ignoreEndGame = value
        End Set
    End Property

    Public Function Clone() As Object Implements System.ICloneable.Clone
        Dim aClone As New cmplib01.Player
        Dim ms As New MemoryStream(1000)
        Dim bf As New BinaryFormatter(Nothing, New StreamingContext(StreamingContextStates.Clone))

        ' serialize object into stream
        bf.Serialize(ms, Me)

        ' position stream pointer back to first byte
        ms.Seek(0, SeekOrigin.Begin)

        ' deserialize into the return object
        aClone = bf.Deserialize(ms)

        ' release memory
        ms.Close()

        Return aClone
    End Function

    Public Sub New()
        Dim rand As New Random(CInt(Date.Now.Second And Integer.MaxValue))
        mCID += 1
        m_PlayerID = rand.Next
    End Sub

    Public Overrides Function ToString() As String
        Return m_PlayerName
    End Function

    Public Function Key() As String
        Return CampaignerGameData.CDGKEY_PLAYER & m_PlayerID
    End Function

    Public Property IsInCombat() As Boolean
        Get
            Return m_IsInCombat
        End Get
        Set(ByVal Value As Boolean)
            m_IsInCombat = Value
        End Set
    End Property

    Public Property PlayerID() As Int64
        Get
            Return m_PlayerID
        End Get
        Set(ByVal Value As Int64)
            m_PlayerID = Value
        End Set
    End Property

    Public Property PlayerName() As String
        Get
            Return m_PlayerName
        End Get
        Set(ByVal Value As String)
            m_PlayerName = Value
        End Set
    End Property

    Public Property Password() As String
        Get
            Return m_Password
        End Get
        Set(ByVal Value As String)
            m_Password = Value
        End Set
    End Property

    Public Property FactionKey() As String
        Get
            Return m_FactionKey
        End Get
        Set(ByVal Value As String)
            m_FactionKey = Value
        End Set
    End Property

    Public Property TurnComplete() As Boolean
        Get
            Return m_TurnComplete
        End Get
        Set(ByVal Value As Boolean)
            m_TurnComplete = Value
        End Set
    End Property

    Public Property UseElementsForPointValue() As Boolean
        Get
            Return m_UseElementsForPointValue
        End Get
        Set(ByVal Value As Boolean)
            m_UseElementsForPointValue = Value
        End Set
    End Property

End Class

#End Region

#Region "Chit Detection"
<Serializable()> Public Class ChitDetection
    Implements ICloneable

    Private m_Chit As ChitMember
    Private m_DetectionLevel As Int16
    Private m_ChitDetectedThisTurn As Boolean = False
    Private _phaseDetected As Integer


    Public Function Clone() As Object Implements System.ICloneable.Clone
        Dim aClone As New cmplib01.ChitDetection
        Dim ms As New MemoryStream(1000)
        Dim bf As New BinaryFormatter(Nothing, New StreamingContext(StreamingContextStates.Clone))

        ' serialize object into stream
        bf.Serialize(ms, Me)

        ' position stream pointer back to first byte
        ms.Seek(0, SeekOrigin.Begin)

        ' deserialize into the return object
        aClone = bf.Deserialize(ms)

        ' release memory
        ms.Close()

        Return aClone
    End Function

    Public Property PhaseDetected() As Integer
        Get
            Return _phaseDetected
        End Get
        Set(ByVal value As Integer)
            _phaseDetected = value
        End Set
    End Property

    Public Property Chit() As ChitMember
        Get
            Return m_Chit
        End Get
        Set(ByVal Value As ChitMember)
            m_Chit = Value
        End Set
    End Property

    Public Property DetectionLevel() As Int16
        Get
            Return m_DetectionLevel
        End Get
        Set(ByVal Value As Int16)
            m_DetectionLevel = Value
        End Set
    End Property

    Public Property ChitDetectedThisTurn() As Boolean
        Get
            Return m_ChitDetectedThisTurn
        End Get
        Set(ByVal Value As Boolean)
            m_ChitDetectedThisTurn = Value
        End Set
    End Property

End Class

<Serializable()> Public Class ChitDetections
    Inherits CollectionBase

    Default Public Property Item(ByVal index As Integer) As ChitDetection
        Get
            Return InnerList.Item(index)
        End Get
        Set(ByVal Value As ChitDetection)
            InnerList.Item(index) = Value
        End Set
    End Property

    Public Sub Add(ByRef item As ChitDetection)
        InnerList.Add(item)
    End Sub

    Public Function contains(ByRef item As ChitDetection) As Boolean
        Return InnerList.Contains(item)
    End Function

End Class

#End Region

#Region "LogEvent"

'<Serializable()> Public Class LogEvent
'    Implements ICloneable

'    Private m_InvokingPlayerName As String
'    Private m_Action As String
'    Private m_ExtendedProperties As String
'    Private m_AuthorityLevel As EventAuthorityLevel
'    Private m_Acknowledged As Boolean
'    Private m_TurnNumber As Int32
'    Private m_Key As String


'    Public Function Clone() As Object Implements System.ICloneable.Clone
'        Dim aClone As New cmplib01.LogEvent
'        Dim ms As New MemoryStream(1000)
'        Dim bf As New BinaryFormatter(Nothing, New StreamingContext(StreamingContextStates.Clone))

'        ' serialize object into stream
'        bf.Serialize(ms, Me)

'        ' position stream pointer back to first byte
'        ms.Seek(0, SeekOrigin.Begin)

'        ' deserialize into the return object
'        aClone = bf.Deserialize(ms)

'        ' release memory
'        ms.Close()

'        Return aClone
'    End Function

'    Public Sub New()
'        '// generates a unique (hopefully) four number and six letter logevent key
'        Dim rand As New Random
'        Dim i As Int16
'        Dim c As Char
'        Dim count As Byte
'        Dim strKey As String

'        For count = 1 To 4
'            i = rand.Next(65, 90)
'            c = Chr(i)
'            strKey = strKey & c
'        Next
'        i = rand.Next(1000, 9999)
'        strKey = strKey & i.ToString

'        m_Key = strKey
'    End Sub

'    Public ReadOnly Property Key() As String
'        Get
'            Return m_Key
'        End Get
'    End Property

'    Public Property TurnNumber() As Int32
'        Get
'            Return m_TurnNumber
'        End Get
'        Set(ByVal Value As Int32)
'            m_TurnNumber = Value
'        End Set
'    End Property

'    Public Property AuthorityLevel() As EventAuthorityLevel
'        Get
'            Return m_AuthorityLevel
'        End Get
'        Set(ByVal Value As EventAuthorityLevel)
'            m_AuthorityLevel = Value
'        End Set
'    End Property

'    Public Property InvokingPlayerName() As String
'        Get
'            Return m_InvokingPlayerName
'        End Get
'        Set(ByVal Value As String)
'            m_InvokingPlayerName = Value
'        End Set
'    End Property

'    Public Property Action() As String
'        Get
'            Return m_Action
'        End Get
'        Set(ByVal Value As String)
'            m_Action = Value
'        End Set
'    End Property

'    Public Property ExtendedProperties() As String
'        Get
'            Return m_ExtendedProperties
'        End Get
'        Set(ByVal Value As String)
'            m_ExtendedProperties = Value
'        End Set
'    End Property

'    Public Property Acknowledged() As Boolean
'        Get
'            Return m_Acknowledged
'        End Get
'        Set(ByVal Value As Boolean)
'            m_Acknowledged = Value
'        End Set
'    End Property

'End Class

#End Region

#Region "Generic Property"
<Serializable()> Public Structure GenericProperty
    Public PropertyName As String    ' used as KEY in GenericProperties
    Public PropertyValue As String
End Structure

<Serializable()> Public Class GenericProperties
    ' simple key/value matching..
    Inherits System.Collections.CollectionBase

    Default Property item(ByVal index As Integer) As GenericProperty
        Get
            Return InnerList.Item(index)
        End Get
        Set(ByVal Value As GenericProperty)
            InnerList.Item(index) = Value
        End Set
    End Property

    Public Sub Add(ByVal GP As GenericProperty)
        InnerList.Add(GP)
    End Sub

    Public Sub Remove(ByVal GP As GenericProperty)
        InnerList.Remove(GP)
    End Sub

End Class

#End Region

#Region "Area Objectives"
' represents bounding areas vital to winning combat. Strategic locations that must be captured and cleared of enemy.

#End Region

#Region "Generic Boundaries"
' used to display an area. Such as national borders, etc.
<Serializable()> Public Class GenericBoundary
    Implements ICloneable

    ' represents a graphics path that describes an arbitrary area.
    Private m_BoundaryName As String
    Private m_BoundaryDescription As String
    Private m_BoundaryColor As Color = Color.Black
    Private m_BoundaryWidth As Integer = 4
    Private m_BoundaryStyle As DashStyle = DashStyle.Dash
    <NonSerialized()> Private m_BoundaryPath As System.Drawing.Drawing2D.PathData      ' of points no doubt to recreate the graphics path, if its a boundary zone
    Private boundaryPoints() As PointF ' the serializable form of pathdata
    <NonSerialized()> Private m_IsSelected As Boolean = False

    Public Overrides Function ToString() As String
        Return m_BoundaryName
    End Function

    Public Function Clone() As Object Implements System.ICloneable.Clone
        Dim aClone As New cmplib01.GenericBoundary
        Dim ms As New MemoryStream(1000)
        Dim bf As New BinaryFormatter(Nothing, New StreamingContext(StreamingContextStates.Clone))

        ' serialize object into stream
        bf.Serialize(ms, Me)

        ' position stream pointer back to first byte
        ms.Seek(0, SeekOrigin.Begin)

        ' deserialize into the return object
        aClone = bf.Deserialize(ms)

        ' release memory
        ms.Close()

        Return aClone
    End Function

    Friend Sub SetBoundaryPathToPoints()
        ' converts the boundarypath to a point arraylist since pathdata cannot be serialized.
        boundaryPoints = m_BoundaryPath.Points
    End Sub

    Friend Sub SetBoundaryPointsToPath()
        ' converts from the serialized arraylist of points to the non-serializable pathdata
        m_BoundaryPath = New System.Drawing.Drawing2D.PathData
        m_BoundaryPath.Points = boundaryPoints

    End Sub

    Public Property IsSelected() As Boolean
        Get
            Return m_IsSelected
        End Get
        Set(ByVal Value As Boolean)
            m_IsSelected = Value
        End Set
    End Property

    Public Property BoundaryColor() As Color
        Get
            Return m_BoundaryColor
        End Get
        Set(ByVal Value As Color)
            m_BoundaryColor = Value
        End Set
    End Property

    Public Property BoundaryStyle() As DashStyle
        Get
            Return m_BoundaryStyle
        End Get
        Set(ByVal Value As DashStyle)
            m_BoundaryStyle = Value
        End Set
    End Property

    Public Property BoundaryWidth() As Integer
        Get
            Return m_BoundaryWidth
        End Get
        Set(ByVal Value As Integer)
            m_BoundaryWidth = Value
        End Set
    End Property

    Public Property BoundaryPath() As System.Drawing.Drawing2D.PathData
        Get
            Return m_BoundaryPath
        End Get
        Set(ByVal Value As System.Drawing.Drawing2D.PathData)
            m_BoundaryPath = Value
        End Set
    End Property

    Public ReadOnly Property BoundaryGraphicsPath() As System.Drawing.Drawing2D.GraphicsPath
        Get
            ' used to return a graphics path of this deployment zone
            Dim graphPath As New System.Drawing.Drawing2D.GraphicsPath
            Dim lastPnt As PointF
            Dim pnt As PointF
            Dim i As Int32

            If boundaryPoints.GetUpperBound(0) <= 1 Then
                Return Nothing
            End If

            For i = 1 To boundaryPoints.GetUpperBound(0) - 1
                lastPnt = boundaryPoints(i - 1)
                pnt = boundaryPoints(i)
                graphPath.AddLine(lastPnt, pnt)
            Next

            Return graphPath
        End Get
    End Property

    Public Property BoundaryName() As String
        Get
            Return m_BoundaryName
        End Get
        Set(ByVal Value As String)
            m_BoundaryName = Value
        End Set
    End Property

    Public Property BoundaryDescription() As String
        Get
            Return m_BoundaryDescription
        End Get
        Set(ByVal Value As String)
            m_BoundaryDescription = Value
        End Set
    End Property

End Class

<Serializable()> Public Class GenericBoundaries
    Inherits Collections.CollectionBase
    Implements ICloneable

    Public Sub DeselectAll()
        Dim bound As GenericBoundary

        For Each bound In InnerList
            bound.IsSelected = False
        Next
    End Sub

    Public Function Clone() As Object Implements System.ICloneable.Clone
        Dim aClone As New cmplib01.GenericBoundaries
        Dim ms As New MemoryStream(1000)
        Dim bf As New BinaryFormatter(Nothing, New StreamingContext(StreamingContextStates.Clone))

        ' serialize object into stream
        bf.Serialize(ms, Me)

        ' position stream pointer back to first byte
        ms.Seek(0, SeekOrigin.Begin)

        ' deserialize into the return object
        aClone = bf.Deserialize(ms)

        ' release memory
        ms.Close()

        Return aClone
    End Function

    Friend Sub SetPathToPoints()
        Dim bound As GenericBoundary

        For Each bound In InnerList
            bound.SetBoundaryPathToPoints()
        Next
    End Sub

    Friend Sub SetPointsToPath()
        Dim bound As GenericBoundary

        For Each bound In InnerList
            bound.SetBoundaryPointsToPath()
        Next
    End Sub

    Default Public Property Item(ByVal index As Integer) As GenericBoundary
        Get
            Return InnerList.Item(index)
        End Get
        Set(ByVal Value As GenericBoundary)
            InnerList.Item(index) = Value
        End Set
    End Property

    Public Sub Add(ByVal bound As GenericBoundary)
        InnerList.Add(bound)
    End Sub

    Public Sub Remove(ByVal bound As GenericBoundary)
        InnerList.Remove(bound)
    End Sub

End Class

#End Region

#Region "Area Objectives"

<Serializable()> Public Class AreaObjective
    Inherits GenericBoundary
    ' the drawing of this guy is always "crosses" for the hatchbrush colors are set
    Private m_OwningFaction As Integer = -1   ' default to none
    Private m_IsContested As Boolean = False
    <NonSerialized()> Private m_IsSelected As Boolean = False
    <NonSerialized()> Private m_Region As Region
    <NonSerialized()> Private m_FactionsPresent As New ArrayList


    ' So far the only difference between  an area objective and a generic boundary is how its drawn. :P And owner.
    Public Property FactionsPresent() As ArrayList
        Get
            Return m_FactionsPresent
        End Get
        Set(ByVal Value As ArrayList)
            m_FactionsPresent = Value
        End Set
    End Property

    Public Property OwningFaction() As Integer
        Get
            Return m_OwningFaction
        End Get
        Set(ByVal Value As Integer)
            m_OwningFaction = Value
        End Set
    End Property

    Public Property IsContested() As Boolean
        Get
            Return m_IsContested
        End Get
        Set(ByVal Value As Boolean)
            m_IsContested = Value
        End Set
    End Property

    Public ReadOnly Property ObjectiveRegion() As Region
        Get
            If m_Region Is Nothing Then CreateRegion()
            Return m_Region
        End Get
    End Property

    Private Sub CreateRegion()
        '// creates the region for this area objective
        m_Region = New Region
        m_Region.Intersect(MyBase.BoundaryGraphicsPath)

    End Sub


End Class

#End Region

#Region "Victory Conditions"
' these are used to award points to a faction. Each list is unique to a faction. They both have their own.
Public Interface IVictoryCondition
    Property VCID() As Integer  ' this may not be very important anymore...
    Property VPValue() As Integer
    Property Achieved() As Boolean
    Property VictoryConditionName() As String
    Property Description() As String
    Property AutomaticVictory() As Boolean
    ReadOnly Property VCType() As VictoryConditionClass_cgd

    ' for expanding in the future
    Property ExtendedProperties() As GenericProperties

End Interface

<Serializable()> Public Class AreaObjectiveVictoryCondition
    Implements IVictoryCondition

    Private m_TargetAreaObjective As AreaObjective ' this points to the area objective that needs to be captured.

    Private m_VCID As Integer
    Private m_VPValue As Integer
    Private m_Achieved As Boolean = False
    Private m_VictoryConditionName As String
    Private m_Description As String
    Private m_AutomaticVictory As Boolean
    Private m_ExtendedProperties As New GenericProperties

    Public Overrides Function ToString() As String
        Dim s As String
        If m_Achieved = True Then
            s = " -Achieved"
        Else
            s = " -Not Achieved"
        End If
        Return m_VictoryConditionName & " " & m_VPValue & s
    End Function

#Region "Properties"
    Public ReadOnly Property VCType() As VictoryConditionClass_cgd Implements IVictoryCondition.VCType
        Get
            Return VictoryConditionClass_cgd.AreaObjective
        End Get
    End Property

    Public Property TargetAreaObjective() As AreaObjective
        Get
            Return m_TargetAreaObjective
        End Get
        Set(ByVal Value As AreaObjective)
            m_TargetAreaObjective = Value
        End Set
    End Property

    Public Property VCID() As Integer Implements IVictoryCondition.VCID
        Get
            Return m_VCID
        End Get
        Set(ByVal Value As Integer)
            m_VCID = Value
        End Set
    End Property

    Public Property VPValue() As Integer Implements IVictoryCondition.VPValue
        Get
            Return m_VPValue
        End Get
        Set(ByVal Value As Integer)
            m_VPValue = Value
        End Set
    End Property

    Public Property Achieved() As Boolean Implements IVictoryCondition.Achieved
        Get
            Return m_Achieved
        End Get
        Set(ByVal Value As Boolean)
            m_Achieved = Value
        End Set
    End Property

    Public Property VictoryConditionName() As String Implements IVictoryCondition.VictoryConditionName
        Get
            Return m_VictoryConditionName
        End Get
        Set(ByVal Value As String)
            m_VictoryConditionName = Value
        End Set
    End Property

    Public Property Description() As String Implements IVictoryCondition.Description
        Get
            Return m_Description
        End Get
        Set(ByVal Value As String)
            m_Description = Value
        End Set
    End Property

    Public Property AutomaticVictory() As Boolean Implements IVictoryCondition.AutomaticVictory
        Get
            Return m_AutomaticVictory
        End Get
        Set(ByVal Value As Boolean)
            m_AutomaticVictory = Value
        End Set
    End Property

    Public Property ExtendedProperties() As GenericProperties Implements IVictoryCondition.ExtendedProperties
        Get
            Return m_ExtendedProperties
        End Get
        Set(ByVal Value As GenericProperties)
            m_ExtendedProperties = Value
        End Set
    End Property

#End Region

End Class

<Serializable()> Public Class AttritionVictoryCondition
    Implements IVictoryCondition

    Private m_DeployedReductionPercent As Single = -1 ' default to not used
    Private m_TotalPointValueReductionPercent As Integer = -1 ' default to used not...
    Private m_UnitType As Integer = -1  ' only a specific unit type

    Private m_VCID As Integer
    Private m_VPValue As Integer
    Private m_Achieved As Boolean = False
    Private m_VictoryConditionName As String
    Private m_Description As String
    Private m_AutomaticVictory As Boolean
    Private m_ExtendedProperties As New GenericProperties

    Public Overrides Function ToString() As String
        Dim s As String
        If m_Achieved = True Then
            s = " -Achieved"
        Else
            s = " -Not Achieved"
        End If
        Return m_VictoryConditionName & " " & m_VPValue & s
    End Function

#Region "Properties"
    Public ReadOnly Property VCType() As VictoryConditionClass_cgd Implements IVictoryCondition.VCType
        Get
            Return VictoryConditionClass_cgd.AttritionObjective
        End Get
    End Property

    Public Property DeployedReductionPercent() As Single
        Get
            Return m_DeployedReductionPercent
        End Get
        Set(ByVal Value As Single)
            m_DeployedReductionPercent = Value
        End Set
    End Property

    Public Property TotalPointValueReductionPercent() As Integer
        Get
            Return m_TotalPointValueReductionPercent
        End Get
        Set(ByVal Value As Integer)
            m_TotalPointValueReductionPercent = Value
        End Set
    End Property

    Public Property UnitType() As Integer
        Get
            Return m_UnitType
        End Get
        Set(ByVal Value As Integer)
            m_UnitType = Value
        End Set
    End Property

    Public Property VCID() As Integer Implements IVictoryCondition.VCID
        Get
            Return m_VCID
        End Get
        Set(ByVal Value As Integer)
            m_VCID = Value
        End Set
    End Property

    Public Property VPValue() As Integer Implements IVictoryCondition.VPValue
        Get
            Return m_VPValue
        End Get
        Set(ByVal Value As Integer)
            m_VPValue = Value
        End Set
    End Property

    Public Property Achieved() As Boolean Implements IVictoryCondition.Achieved
        Get
            Return m_Achieved
        End Get
        Set(ByVal Value As Boolean)
            m_Achieved = Value
        End Set
    End Property

    Public Property VictoryConditionName() As String Implements IVictoryCondition.VictoryConditionName
        Get
            Return m_VictoryConditionName
        End Get
        Set(ByVal Value As String)
            m_VictoryConditionName = Value
        End Set
    End Property

    Public Property Description() As String Implements IVictoryCondition.Description
        Get
            Return m_Description
        End Get
        Set(ByVal Value As String)
            m_Description = Value
        End Set
    End Property

    Public Property AutomaticVictory() As Boolean Implements IVictoryCondition.AutomaticVictory
        Get
            Return m_AutomaticVictory
        End Get
        Set(ByVal Value As Boolean)
            m_AutomaticVictory = Value
        End Set
    End Property

    Public Property ExtendedProperties() As GenericProperties Implements IVictoryCondition.ExtendedProperties
        Get
            Return m_ExtendedProperties
        End Get
        Set(ByVal Value As GenericProperties)
            m_ExtendedProperties = Value
        End Set
    End Property

#End Region

End Class

<Serializable()> Public Class ChitDestructionVictoryCondition
    Implements IVictoryCondition

    Private m_ChitToDestroy As ChitMember

    Private m_VCID As Integer
    Private m_VPValue As Integer
    Private m_Achieved As Boolean = False
    Private m_VictoryConditionName As String
    Private m_Description As String
    Private m_AutomaticVictory As Boolean
    Private m_ExtendedProperties As New GenericProperties

    Public Overrides Function ToString() As String
        Dim s As String
        If m_Achieved = True Then
            s = " -Achieved"
        Else
            s = " -Not Achieved"
        End If
        Return m_VictoryConditionName & " " & m_VPValue & s
    End Function

#Region "Properties"
    Public ReadOnly Property VCType() As VictoryConditionClass_cgd Implements IVictoryCondition.VCType
        Get
            Return VictoryConditionClass_cgd.ChitDestruction
        End Get
    End Property

    Public Property ChitToDestroy() As ChitMember
        Get
            Return m_ChitToDestroy
        End Get
        Set(ByVal Value As ChitMember)
            m_ChitToDestroy = Value
        End Set
    End Property

    Public Property VCID() As Integer Implements IVictoryCondition.VCID
        Get
            Return m_VCID
        End Get
        Set(ByVal Value As Integer)
            m_VCID = Value
        End Set
    End Property

    Public Property VPValue() As Integer Implements IVictoryCondition.VPValue
        Get
            Return m_VPValue
        End Get
        Set(ByVal Value As Integer)
            m_VPValue = Value
        End Set
    End Property

    Public Property Achieved() As Boolean Implements IVictoryCondition.Achieved
        Get
            Return m_Achieved
        End Get
        Set(ByVal Value As Boolean)
            m_Achieved = Value
        End Set
    End Property

    Public Property VictoryConditionName() As String Implements IVictoryCondition.VictoryConditionName
        Get
            Return m_VictoryConditionName
        End Get
        Set(ByVal Value As String)
            m_VictoryConditionName = Value
        End Set
    End Property

    Public Property Description() As String Implements IVictoryCondition.Description
        Get
            Return m_Description
        End Get
        Set(ByVal Value As String)
            m_Description = Value
        End Set
    End Property

    Public Property AutomaticVictory() As Boolean Implements IVictoryCondition.AutomaticVictory
        Get
            Return m_AutomaticVictory
        End Get
        Set(ByVal Value As Boolean)
            m_AutomaticVictory = Value
        End Set
    End Property

    Public Property ExtendedProperties() As GenericProperties Implements IVictoryCondition.ExtendedProperties
        Get
            Return m_ExtendedProperties
        End Get
        Set(ByVal Value As GenericProperties)
            m_ExtendedProperties = Value
        End Set
    End Property

#End Region

End Class

<Serializable()> Public Class ResourceVictoryCondition
    Implements IVictoryCondition

    Private m_ResourceType As ResourceType
    Private m_AmountNeeded As Integer

    Private m_VCID As Integer
    Private m_VPValue As Integer
    Private m_Achieved As Boolean = False
    Private m_VictoryConditionName As String
    Private m_Description As String
    Private m_AutomaticVictory As Boolean
    Private m_ExtendedProperties As New GenericProperties

    Public Overrides Function ToString() As String
        Dim s As String
        If m_Achieved = True Then
            s = " -Achieved"
        Else
            s = " -Not Achieved"
        End If
        Return m_VictoryConditionName & " " & m_VPValue & s
    End Function

#Region "Properties"
    Public ReadOnly Property VCType() As VictoryConditionClass_cgd Implements IVictoryCondition.VCType
        Get
            Return VictoryConditionClass_cgd.Resource
        End Get
    End Property

    Public Property TargetResourceType() As ResourceType
        Get
            Return m_ResourceType
        End Get
        Set(ByVal Value As ResourceType)
            m_ResourceType = Value
        End Set
    End Property

    Public Property AmountNeeded() As Integer
        Get
            Return m_AmountNeeded
        End Get
        Set(ByVal Value As Integer)
            m_AmountNeeded = Value
        End Set
    End Property

    Public Property VCID() As Integer Implements IVictoryCondition.VCID
        Get
            Return m_VCID
        End Get
        Set(ByVal Value As Integer)
            m_VCID = Value
        End Set
    End Property

    Public Property VPValue() As Integer Implements IVictoryCondition.VPValue
        Get
            Return m_VPValue
        End Get
        Set(ByVal Value As Integer)
            m_VPValue = Value
        End Set
    End Property

    Public Property Achieved() As Boolean Implements IVictoryCondition.Achieved
        Get
            Return m_Achieved
        End Get
        Set(ByVal Value As Boolean)
            m_Achieved = Value
        End Set
    End Property

    Public Property VictoryConditionName() As String Implements IVictoryCondition.VictoryConditionName
        Get
            Return m_VictoryConditionName
        End Get
        Set(ByVal Value As String)
            m_VictoryConditionName = Value
        End Set
    End Property

    Public Property Description() As String Implements IVictoryCondition.Description
        Get
            Return m_Description
        End Get
        Set(ByVal Value As String)
            m_Description = Value
        End Set
    End Property

    Public Property AutomaticVictory() As Boolean Implements IVictoryCondition.AutomaticVictory
        Get
            Return m_AutomaticVictory
        End Get
        Set(ByVal Value As Boolean)
            m_AutomaticVictory = Value
        End Set
    End Property

    Public Property ExtendedProperties() As GenericProperties Implements IVictoryCondition.ExtendedProperties
        Get
            Return m_ExtendedProperties
        End Get
        Set(ByVal Value As GenericProperties)
            m_ExtendedProperties = Value
        End Set
    End Property

#End Region

End Class

<Serializable()> Public Class FinalVictoryCondition
    Implements IVictoryCondition
    ' used to set the winning amount of victory points. Ie... this side wins if it gets this many vps.
    Private m_WinningVictoryPointValue As Integer

    Private m_VCID As Integer
    Private m_VPValue As Integer
    Private m_Achieved As Boolean = False
    Private m_VictoryConditionName As String = "Final Victory"
    Private m_Description As String
    Private m_AutomaticVictory As Boolean = True
    Private m_ExtendedProperties As New GenericProperties

    Public Overrides Function ToString() As String
        Dim s As String
        If m_Achieved = True Then
            s = " -Achieved"
        Else
            s = " -Not Achieved"
        End If
        Return m_VictoryConditionName & " " & m_VPValue & s
    End Function

#Region "Properties"

    Public Property WinningVictoryPointValue() As Integer
        Get
            Return m_WinningVictoryPointValue
        End Get
        Set(ByVal Value As Integer)
            m_WinningVictoryPointValue = Value
        End Set
    End Property

    Public ReadOnly Property VCType() As VictoryConditionClass_cgd Implements IVictoryCondition.VCType
        Get
            Return VictoryConditionClass_cgd.Final
        End Get
    End Property

    Public Property VCID() As Integer Implements IVictoryCondition.VCID
        Get
            Return m_VCID
        End Get
        Set(ByVal Value As Integer)
            m_VCID = Value
        End Set
    End Property

    Public Property VPValue() As Integer Implements IVictoryCondition.VPValue
        Get
            Return m_VPValue
        End Get
        Set(ByVal Value As Integer)
            m_VPValue = Value
        End Set
    End Property

    Public Property Achieved() As Boolean Implements IVictoryCondition.Achieved
        Get
            Return m_Achieved
        End Get
        Set(ByVal Value As Boolean)
            m_Achieved = Value
        End Set
    End Property

    Public Property VictoryConditionName() As String Implements IVictoryCondition.VictoryConditionName
        Get
            Return m_VictoryConditionName
        End Get
        Set(ByVal Value As String)
            m_VictoryConditionName = Value
        End Set
    End Property

    Public Property Description() As String Implements IVictoryCondition.Description
        Get
            Return m_Description
        End Get
        Set(ByVal Value As String)
            m_Description = Value
        End Set
    End Property

    Public Property AutomaticVictory() As Boolean Implements IVictoryCondition.AutomaticVictory
        Get
            Return m_AutomaticVictory
        End Get
        Set(ByVal Value As Boolean)
            m_AutomaticVictory = Value
        End Set
    End Property

    Public Property ExtendedProperties() As GenericProperties Implements IVictoryCondition.ExtendedProperties
        Get
            Return m_ExtendedProperties
        End Get
        Set(ByVal Value As GenericProperties)
            m_ExtendedProperties = Value
        End Set
    End Property

#End Region

End Class

<Serializable()> Public Class VictoryConditions
    Inherits System.Collections.CollectionBase
    Implements ICloneable

    Public Function Clone() As Object Implements System.ICloneable.Clone
        Dim aClone As New cmplib01.VictoryConditions
        Dim ms As New MemoryStream(1000)
        Dim bf As New BinaryFormatter(Nothing, New StreamingContext(StreamingContextStates.Clone))

        ' serialize object into stream
        bf.Serialize(ms, Me)

        ' position stream pointer back to first byte
        ms.Seek(0, SeekOrigin.Begin)

        ' deserialize into the return object
        aClone = bf.Deserialize(ms)

        ' release memory
        ms.Close()

        Return aClone
    End Function


    Public Function TotalVictoryPointValue() As Integer
        ' returns the total value of this faction's victory points, for those that are achieved
        Dim total As Integer
        Dim VC As IVictoryCondition

        For Each VC In InnerList
            If VC.Achieved Then
                total += VC.VPValue
            End If
        Next
        Return total
    End Function

    Public Sub AssignAchievedConditions(ByRef ptrGameData As CampaignerGameData)
        ' rolls through to check if each VC has been achieved.
        'TODO: AssignAchievedConditions
    End Sub

    Public Sub Add(ByVal value As IVictoryCondition)
        InnerList.Add(value)
    End Sub

    Default Property item(ByVal index As Integer) As IVictoryCondition
        Get
            Return CType(InnerList(index), Rule)
        End Get
        Set(ByVal Value As IVictoryCondition)
            InnerList(index) = Value
        End Set
    End Property

    Public Sub Remove(ByRef value As IVictoryCondition)
        InnerList.Remove(value)
    End Sub

End Class


#End Region


<Serializable()> Public Class PhaseDetectionEvents : Inherits ChitDetectionEvents
    '// this is a record of detection for a particular enemy at a particular point in the game. It points to the detected item's icon and det level, and location
    Private _globalPhase As Long '// the phase all of the events in here take place.

    Public Property globalphase() As Long
        Get
            Return _globalPhase
        End Get
        Set(ByVal value As Long)
            _globalPhase = value
        End Set
    End Property

End Class

<Serializable()> Public Class ChitDetectionEvent
    Private _location As Point
    Private _detLevel As ChitDetection

    Public Property Location() As Point
        Get
            Return _location
        End Get
        Set(ByVal value As Point)
            _location = value
        End Set
    End Property

    Public Property DetLevel() As ChitDetection
        Get
            Return _detLevel
        End Get
        Set(ByVal value As ChitDetection)
            _detLevel = value
        End Set
    End Property

End Class

<Serializable()> Public Class ChitDetectionEvents : Inherits CollectionBase

    Default Public Property item(ByVal index As Integer) As ChitDetectionEvent
        Get
            Return InnerList.Item(index)
        End Get
        Set(ByVal value As ChitDetectionEvent)
            InnerList.Item(index) = value
        End Set
    End Property

    Public Sub add(ByVal value As ChitDetectionEvent)
        InnerList.Add(value)
    End Sub

    Public Sub remove(ByVal obj As ChitDetectionEvent)
        InnerList.Remove(obj)
    End Sub
End Class


<Serializable()> Public Structure CampaignerLogEvent
    Public logMessage As String    '// the action
    Public logSource As String   '// the player name
    Public timeStamp As String '// elapsed game time this action occured
    Public ExtendedProperties As String
    Public AuthorityLevel As EventAuthorityLevel

    Public Sub New(ByVal logmess As String, ByVal source As String, ByVal time As String, ByVal properties As String, ByVal authLevel As EventAuthorityLevel)
        logMessage = logmess
        logSource = source
        timeStamp = time
        ExtendedProperties = properties
        authLevel = AuthorityLevel
    End Sub

End Structure



<Serializable()> Public Class EndGame
    Private _gameended As Boolean
    Private _turnRunout As Boolean
    Private _victoryWin As Boolean
    Private _ignore As Boolean

    Public Property Ignore() As Boolean
        Get
            Return _ignore
        End Get
        Set(ByVal value As Boolean)
            _ignore = value
        End Set
    End Property

    Public Property GameEnded() As Boolean
        Get
            Return _gameended
        End Get
        Set(ByVal value As Boolean)
            _gameended = value
        End Set
    End Property

    Public Property turnRunOut() As Boolean
        Get
            Return _turnRunout
        End Get
        Set(ByVal value As Boolean)
            _turnRunout = value
        End Set
    End Property

    Public Property VictoryWin() As Boolean
        Get
            Return _victoryWin
        End Get
        Set(ByVal value As Boolean)
            _victoryWin = value
        End Set
    End Property

End Class



Module modUnexpectedExceptionHandler

    Public g_ExceptionLogFileName As String = System.AppDomain.CurrentDomain.BaseDirectory & "CBuilder.log"

    Friend Sub HandleException(ByVal strModule As String, ByVal e As Exception)

        'purpose: to provide logging information on errors that are NOT expected... ie handled with 'Catch ex as Exception'
        '             instead of 'Catch ex as System.Data.DataException' and so forth. These are UNEXPECTED errors. :P

        Dim strMessage As String
        Dim strCaption As String

        Try
            strMessage = "Timestamp: " & Now() & vbCrLf & _
                                "Exception: " & e.Message & vbCrLf & _
                               "Module: " & strModule & vbCrLf & _
                               "Method: " & e.TargetSite.Name & vbCrLf

            ' build the title bar.
            With System.Reflection.Assembly.GetExecutingAssembly.GetName.Version
                strCaption = "Unexpected Exception. Version " & _
                                 .Major & "." & .Minor & Format(.Revision, "0000")
            End With

            ' open streamwriter to save, or append to log file. The log text has the inclusion of the stack trace.
            Dim objStream As New System.IO.StreamWriter(g_ExceptionLogFileName, True)
            Dim logText As String = strMessage & "Stack: " & e.StackTrace & vbCrLf

            ' write yonder message to da stream
            objStream.WriteLine(logText)
            ' send it away to da file and then close
            objStream.Flush()
            objStream.Close()

            ' show the error to yonder user with a perty message that this is a totally unexpected exception
            MessageBox.Show(strMessage, strCaption, MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
        Finally

        End Try

    End Sub

End Module

